Revision: 21031
Author: [email protected]
Date: Tue Apr 29 00:04:31 2014 UTC
Log: Version 3.26.27 (based on bleeding_edge revision r21017)
Error stack getter should not overwrite itself with a data property (issue
3294).
Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=21031
Added:
/trunk/test/mjsunit/regress/regress-3294.js
Modified:
/trunk/ChangeLog
/trunk/src/accessors.cc
/trunk/src/accessors.h
/trunk/src/arm/lithium-gap-resolver-arm.cc
/trunk/src/arm/lithium-gap-resolver-arm.h
/trunk/src/array.js
/trunk/src/bootstrapper.cc
/trunk/src/frames.cc
/trunk/src/heap.cc
/trunk/src/heap.h
/trunk/src/hydrogen.cc
/trunk/src/incremental-marking.cc
/trunk/src/mark-compact.cc
/trunk/src/mark-compact.h
/trunk/src/messages.js
/trunk/src/mips/code-stubs-mips.cc
/trunk/src/mips/full-codegen-mips.cc
/trunk/src/runtime.h
/trunk/src/spaces.cc
/trunk/src/spaces.h
/trunk/src/version.cc
/trunk/test/cctest/test-debug.cc
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-3294.js Tue Apr 29 00:04:31 2014 UTC
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var e = new Error('message');
+var keys = Object.keys(e);
+e.stack;
+assertEquals(keys, Object.keys(e));
=======================================
--- /trunk/ChangeLog Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/ChangeLog Tue Apr 29 00:04:31 2014 UTC
@@ -1,3 +1,11 @@
+2014-04-29: Version 3.26.27
+
+ Error stack getter should not overwrite itself with a data property
+ (issue 3294).
+
+ Performance and stability improvements on all platforms.
+
+
2014-04-28: Version 3.26.26
Expose promise value through promise mirror (issue 3093).
=======================================
--- /trunk/src/accessors.cc Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/accessors.cc Tue Apr 29 00:04:31 2014 UTC
@@ -1096,26 +1096,47 @@
}
-Object* Accessors::FunctionGetArguments(Isolate* isolate,
- Object* object,
- void*) {
+void Accessors::FunctionArgumentsGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
- Handle<JSFunction> function;
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+
{
DisallowHeapAllocation no_allocation;
- JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
- if (holder == NULL) return isolate->heap()->undefined_value();
- function = Handle<JSFunction>(holder, isolate);
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
}
- return *GetFunctionArguments(isolate, function);
+
+ Handle<JSFunction> function;
+ Handle<Object> result;
+ if (maybe_function.ToHandle(&function)) {
+ result = GetFunctionArguments(isolate, function);
+ } else {
+ result = isolate->factory()->undefined_value();
+ }
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::FunctionArguments = {
- FunctionGetArguments,
- ReadOnlySetAccessor,
- 0
-};
+void Accessors::FunctionArgumentsSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->arguments_string(),
+ &FunctionArgumentsGetter,
+ &FunctionArgumentsSetter,
+ attributes);
+}
//
=======================================
--- /trunk/src/accessors.h Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/accessors.h Tue Apr 29 00:04:31 2014 UTC
@@ -37,11 +37,11 @@
// The list of accessor descriptors. This is a second-order macro
// taking a macro to be applied to all accessor descriptor names.
#define ACCESSOR_DESCRIPTOR_LIST(V) \
- V(FunctionArguments) \
V(FunctionCaller) \
V(ArrayLength)
#define ACCESSOR_INFO_LIST(V) \
+ V(FunctionArguments) \
V(FunctionName) \
V(FunctionLength) \
V(FunctionPrototype) \
@@ -114,21 +114,6 @@
int* object_offset);
private:
- // Accessor functions only used through the descriptor.
- static Object* FunctionSetPrototype(Isolate* isolate,
- JSObject* object,
- Object*,
- void*);
- static Object* FunctionGetPrototype(Isolate* isolate,
- Object* object,
- void*);
- static Object* FunctionGetLength(Isolate* isolate,
- Object* object,
- void*);
- static Object* FunctionGetName(Isolate* isolate, Object* object, void*);
- static Object* FunctionGetArguments(Isolate* isolate,
- Object* object,
- void*);
static Object* FunctionGetCaller(Isolate* isolate,
Object* object,
void*);
=======================================
--- /trunk/src/arm/lithium-gap-resolver-arm.cc Fri Oct 25 09:22:31 2013 UTC
+++ /trunk/src/arm/lithium-gap-resolver-arm.cc Tue Apr 29 00:04:31 2014 UTC
@@ -33,11 +33,22 @@
namespace v8 {
namespace internal {
-static const Register kSavedValueRegister = { 9 };
+// We use the root register to spill a value while breaking a cycle in
parallel
+// moves. We don't need access to roots while resolving the move list and
using
+// the root register has two advantages:
+// - It is not in crankshaft allocatable registers list, so it can't
interfere
+// with any of the moves we are resolving.
+// - We don't need to push it on the stack, as we can reload it with its
value
+// once we have resolved a cycle.
+#define kSavedValueRegister kRootRegister
+
LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner), moves_(32, owner->zone()), root_index_(0),
in_cycle_(false),
- saved_destination_(NULL) { }
+ saved_destination_(NULL), need_to_restore_root_(false) { }
+
+
+#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::Resolve(LParallelMove* parallel_move) {
@@ -66,6 +77,12 @@
EmitMove(i);
}
}
+
+ if (need_to_restore_root_) {
+ ASSERT(kSavedValueRegister.is(kRootRegister));
+ __ InitializeRootRegister();
+ need_to_restore_root_ = false;
+ }
moves_.Rewind(0);
}
@@ -155,20 +172,21 @@
#endif
}
-#define __ ACCESS_MASM(cgen_->masm())
void LGapResolver::BreakCycle(int index) {
- // We save in a register the value that should end up in the source of
- // moves_[root_index]. After performing all moves in the tree rooted
- // in that move, we save the value to that source.
+ // We save in a register the source of that move and we remember its
+ // destination. Then we mark this move as resolved so the cycle is
+ // broken and we can perform the other moves.
ASSERT(moves_[index].destination()->Equals(moves_[root_index_].source()));
ASSERT(!in_cycle_);
in_cycle_ = true;
LOperand* source = moves_[index].source();
saved_destination_ = moves_[index].destination();
if (source->IsRegister()) {
+ need_to_restore_root_ = true;
__ mov(kSavedValueRegister, cgen_->ToRegister(source));
} else if (source->IsStackSlot()) {
+ need_to_restore_root_ = true;
__ ldr(kSavedValueRegister, cgen_->ToMemOperand(source));
} else if (source->IsDoubleRegister()) {
__ vmov(kScratchDoubleReg, cgen_->ToDoubleRegister(source));
@@ -186,7 +204,6 @@
ASSERT(in_cycle_);
ASSERT(saved_destination_ != NULL);
- // Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
if (saved_destination_->IsRegister()) {
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
} else if (saved_destination_->IsStackSlot()) {
@@ -226,20 +243,15 @@
} else {
ASSERT(destination->IsStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination);
- if (in_cycle_) {
- if (!destination_operand.OffsetIsUint12Encodable()) {
- // ip is overwritten while saving the value to the destination.
- // Therefore we can't use ip. It is OK if the read from the
source
- // destroys ip, since that happens before the value is read.
- __ vldr(kScratchDoubleReg.low(), source_operand);
- __ vstr(kScratchDoubleReg.low(), destination_operand);
- } else {
- __ ldr(ip, source_operand);
- __ str(ip, destination_operand);
- }
+ if (!destination_operand.OffsetIsUint12Encodable()) {
+ // ip is overwritten while saving the value to the destination.
+ // Therefore we can't use ip. It is OK if the read from the source
+ // destroys ip, since that happens before the value is read.
+ __ vldr(kScratchDoubleReg.low(), source_operand);
+ __ vstr(kScratchDoubleReg.low(), destination_operand);
} else {
- __ ldr(kSavedValueRegister, source_operand);
- __ str(kSavedValueRegister, destination_operand);
+ __ ldr(ip, source_operand);
+ __ str(ip, destination_operand);
}
}
@@ -261,14 +273,14 @@
} else {
ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are
gone.
+ need_to_restore_root_ = true;
Representation r = cgen_->IsSmi(constant_source)
? Representation::Smi() : Representation::Integer32();
if (cgen_->IsInteger32(constant_source)) {
__ mov(kSavedValueRegister,
Operand(cgen_->ToRepresentation(constant_source, r)));
} else {
- __ Move(kSavedValueRegister,
- cgen_->ToHandle(constant_source));
+ __ Move(kSavedValueRegister, cgen_->ToHandle(constant_source));
}
__ str(kSavedValueRegister, cgen_->ToMemOperand(destination));
}
@@ -290,16 +302,11 @@
ASSERT(destination->IsDoubleStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination);
if (in_cycle_) {
- // kSavedDoubleValueRegister was used to break the cycle,
- // but kSavedValueRegister is free.
- MemOperand source_high_operand =
- cgen_->ToHighMemOperand(source);
- MemOperand destination_high_operand =
- cgen_->ToHighMemOperand(destination);
- __ ldr(kSavedValueRegister, source_operand);
- __ str(kSavedValueRegister, destination_operand);
- __ ldr(kSavedValueRegister, source_high_operand);
- __ str(kSavedValueRegister, destination_high_operand);
+ // kScratchDoubleReg was used to break the cycle.
+ __ vstm(db_w, sp, kScratchDoubleReg, kScratchDoubleReg);
+ __ vldr(kScratchDoubleReg, source_operand);
+ __ vstr(kScratchDoubleReg, destination_operand);
+ __ vldm(ia_w, sp, kScratchDoubleReg, kScratchDoubleReg);
} else {
__ vldr(kScratchDoubleReg, source_operand);
__ vstr(kScratchDoubleReg, destination_operand);
=======================================
--- /trunk/src/arm/lithium-gap-resolver-arm.h Wed Aug 21 11:18:12 2013 UTC
+++ /trunk/src/arm/lithium-gap-resolver-arm.h Tue Apr 29 00:04:31 2014 UTC
@@ -76,6 +76,10 @@
int root_index_;
bool in_cycle_;
LOperand* saved_destination_;
+
+ // We use the root register as a scratch in a few places. When that
happens,
+ // this flag is set to indicate that it needs to be restored.
+ bool need_to_restore_root_;
};
} } // namespace v8::internal
=======================================
--- /trunk/src/array.js Thu Apr 24 00:05:05 2014 UTC
+++ /trunk/src/array.js Tue Apr 29 00:04:31 2014 UTC
@@ -1147,28 +1147,16 @@
var result = new $Array();
var accumulator = new InternalArray();
var accumulator_length = 0;
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (%_CallFunction(receiver, element, i, array, f)) {
- accumulator[accumulator_length++] = element;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (%_CallFunction(receiver, element, i, array, f)) {
+ accumulator[accumulator_length++] = element;
}
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (%_CallFunction(receiver, element, i, array, f)) {
- accumulator[accumulator_length++] = element;
- }
- }
- }
- // End of duplicate.
}
%MoveArrayContents(accumulator, result);
return result;
@@ -1192,24 +1180,14 @@
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- %_CallFunction(receiver, element, i, array, f);
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ %_CallFunction(receiver, element, i, array, f);
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- %_CallFunction(receiver, element, i, array, f);
- }
- }
- // End of duplicate.
}
}
@@ -1233,24 +1211,14 @@
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (%_CallFunction(receiver, element, i, array, f)) return true;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (%_CallFunction(receiver, element, i, array, f)) return true;
}
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (%_CallFunction(receiver, element, i, array, f)) return true;
- }
- }
- // End of duplicate.
}
return false;
}
@@ -1273,24 +1241,14 @@
receiver = ToObject(receiver);
}
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- if (!%_CallFunction(receiver, element, i, array, f)) return false;
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- if (!%_CallFunction(receiver, element, i, array, f)) return false;
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ if (!%_CallFunction(receiver, element, i, array, f)) return false;
}
- // End of duplicate.
}
return true;
}
@@ -1314,24 +1272,14 @@
var result = new $Array();
var accumulator = new InternalArray(length);
- if (%DebugCallbackSupportsStepping(f)) {
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(f);
- accumulator[i] = %_CallFunction(receiver, element, i, array, f);
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (var i = 0; i < length; i++) {
- if (i in array) {
- var element = array[i];
- accumulator[i] = %_CallFunction(receiver, element, i, array, f);
- }
+ var stepping = %_DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ accumulator[i] = %_CallFunction(receiver, element, i, array, f);
}
- // End of duplicate.
}
%MoveArrayContents(accumulator, result);
return result;
@@ -1471,27 +1419,14 @@
}
var receiver = %GetDefaultReceiver(callback);
-
- if (%DebugCallbackSupportsStepping(callback)) {
- for (; i < length; i++) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(callback);
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (; i < length; i++) {
- if (i in array) {
- var element = array[i];
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
+ var stepping = %_DebugCallbackSupportsStepping(callback);
+ for (; i < length; i++) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(callback);
+ current = %_CallFunction(receiver, current, element, i, array,
callback);
}
- // End of duplicate.
}
return current;
}
@@ -1521,27 +1456,14 @@
}
var receiver = %GetDefaultReceiver(callback);
-
- if (%DebugCallbackSupportsStepping(callback)) {
- for (; i >= 0; i--) {
- if (i in array) {
- var element = array[i];
- // Prepare break slots for debugger step in.
- %DebugPrepareStepInIfStepping(callback);
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
- }
- } else {
- // This is a duplicate of the previous loop sans debug stepping.
- for (; i >= 0; i--) {
- if (i in array) {
- var element = array[i];
- current =
- %_CallFunction(receiver, current, element, i, array, callback);
- }
+ var stepping = %_DebugCallbackSupportsStepping(callback);
+ for (; i >= 0; i--) {
+ if (i in array) {
+ var element = array[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(callback);
+ current = %_CallFunction(receiver, current, element, i, array,
callback);
}
- // End of duplicate.
}
return current;
}
=======================================
--- /trunk/src/bootstrapper.cc Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/bootstrapper.cc Tue Apr 29 00:04:31 2014 UTC
@@ -388,7 +388,6 @@
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
Map::EnsureDescriptorSlack(map, size);
- Handle<Foreign>
args(factory()->NewForeign(&Accessors::FunctionArguments));
Handle<Foreign>
caller(factory()->NewForeign(&Accessors::FunctionCaller));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
@@ -407,8 +406,11 @@
name, attribs);
map->AppendDescriptor(&d);
}
+ Handle<AccessorInfo> args =
+ Accessors::FunctionArgumentsInfo(isolate(), attribs);
{ // Add arguments.
- CallbacksDescriptor d(factory()->arguments_string(), args, attribs);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(args->name())),
+ args, attribs);
map->AppendDescriptor(&d);
}
{ // Add caller.
=======================================
--- /trunk/src/frames.cc Fri Apr 25 00:05:01 2014 UTC
+++ /trunk/src/frames.cc Tue Apr 29 00:04:31 2014 UTC
@@ -990,13 +990,10 @@
it.Next(); // Skip height.
// The translation commands are ordered and the receiver is always
- // at the first position. Since we are always at a call when we need
- // to construct a stack trace, the receiver is always in a stack
slot.
+ // at the first position.
+ // If we are at a call, the receiver is always in a stack slot.
+ // Otherwise we are not guaranteed to get the receiver value.
opcode = static_cast<Translation::Opcode>(it.Next());
- ASSERT(opcode == Translation::STACK_SLOT ||
- opcode == Translation::LITERAL ||
- opcode == Translation::CAPTURED_OBJECT ||
- opcode == Translation::DUPLICATED_OBJECT);
int index = it.Next();
// Get the correct receiver in the optimized frame.
@@ -1020,6 +1017,7 @@
: this->GetParameter(parameter_index);
}
} else {
+ // The receiver is not in a stack slot nor in a literal. We give
up.
// TODO(3029): Materializing a captured object (or duplicated
// object) is hard, we return undefined for now. This breaks the
// produced stack trace, as constructor frames aren't marked as
=======================================
--- /trunk/src/heap.cc Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/heap.cc Tue Apr 29 00:04:31 2014 UTC
@@ -1517,9 +1517,6 @@
incremental_marking()->PrepareForScavenge();
- paged_space(OLD_DATA_SPACE)->EnsureSweeperProgress(new_space_.Size());
- paged_space(OLD_POINTER_SPACE)->EnsureSweeperProgress(new_space_.Size());
-
// Flip the semispaces. After flipping, to space is empty, from space
has
// live objects.
new_space_.Flip();
=======================================
--- /trunk/src/heap.h Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/heap.h Tue Apr 29 00:04:31 2014 UTC
@@ -1548,12 +1548,6 @@
IncrementalMarking* incremental_marking() {
return &incremental_marking_;
}
-
- bool EnsureSweepersProgressed(int step_size) {
- bool sweeping_complete =
old_data_space()->EnsureSweeperProgress(step_size);
- sweeping_complete &=
old_pointer_space()->EnsureSweeperProgress(step_size);
- return sweeping_complete;
- }
ExternalStringTable* external_string_table() {
return &external_string_table_;
=======================================
--- /trunk/src/hydrogen.cc Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/hydrogen.cc Tue Apr 29 00:04:31 2014 UTC
@@ -11053,6 +11053,14 @@
Add<HDebugBreak>();
return ast_context()->ReturnValue(graph()->GetConstant0());
}
+
+
+void HOptimizedGraphBuilder::GenerateDebugCallbackSupportsStepping(
+ CallRuntime* call) {
+ ASSERT(call->arguments()->length() == 1);
+ // Debugging is not supported in optimized code.
+ return ast_context()->ReturnValue(graph()->GetConstantFalse());
+}
#undef CHECK_BAILOUT
=======================================
--- /trunk/src/incremental-marking.cc Mon Apr 28 11:21:54 2014 UTC
+++ /trunk/src/incremental-marking.cc Tue Apr 29 00:04:31 2014 UTC
@@ -909,7 +909,7 @@
}
if (state_ == SWEEPING) {
- if
(heap_->EnsureSweepersProgressed(static_cast<int>(bytes_to_process))) {
+ if
(!heap_->mark_compact_collector()->IsConcurrentSweepingInProgress()) {
bytes_scanned_ = 0;
StartMarking(PREVENT_COMPACTION);
}
=======================================
--- /trunk/src/mark-compact.cc Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/mark-compact.cc Tue Apr 29 00:04:31 2014 UTC
@@ -627,14 +627,14 @@
}
ParallelSweepSpacesComplete();
sweeping_pending_ = false;
- RefillFreeLists(heap()->paged_space(OLD_DATA_SPACE));
- RefillFreeLists(heap()->paged_space(OLD_POINTER_SPACE));
+ RefillFreeList(heap()->paged_space(OLD_DATA_SPACE));
+ RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE));
heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes();
heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
}
-intptr_t MarkCompactCollector::RefillFreeLists(PagedSpace* space) {
+void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
FreeList* free_list;
if (space == heap()->old_pointer_space()) {
@@ -644,13 +644,12 @@
} else {
// Any PagedSpace might invoke RefillFreeLists, so we need to make sure
// to only refill them for old data and pointer spaces.
- return 0;
+ return;
}
intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
space->AddToAccountingStats(freed_bytes);
space->DecrementUnsweptFreeBytes(freed_bytes);
- return freed_bytes;
}
=======================================
--- /trunk/src/mark-compact.h Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/mark-compact.h Tue Apr 29 00:04:31 2014 UTC
@@ -694,7 +694,7 @@
void WaitUntilSweepingCompleted();
- intptr_t RefillFreeLists(PagedSpace* space);
+ void RefillFreeList(PagedSpace* space);
bool AreSweeperThreadsActivated();
@@ -713,7 +713,7 @@
void MarkWeakObjectToCodeTable();
// Special case for processing weak references in a full collection. We
need
- // to artifically keep AllocationSites alive for a time.
+ // to artificially keep AllocationSites alive for a time.
void MarkAllocationSite(AllocationSite* site);
private:
=======================================
--- /trunk/src/messages.js Tue Apr 15 00:04:44 2014 UTC
+++ /trunk/src/messages.js Tue Apr 29 00:04:31 2014 UTC
@@ -1157,6 +1157,18 @@
stackTraceLimit);
var error_string = FormatErrorString(obj);
+
+ // Set the 'stack' property on the receiver. If the receiver is the
same as
+ // holder of this setter, the accessor pair is turned into a data
property.
+ var setter = function(v) {
+ // Set data property on the receiver (not necessarily holder).
+ %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
+ if (this === obj) {
+ // Release context values if holder is the same as the receiver.
+ stack = error_string = UNDEFINED;
+ }
+ };
+
// The holder of this getter ('obj') may not be the receiver ('this').
// When this getter is called the first time, we use the context values
to
// format a stack trace string and turn this accessor pair into a data
@@ -1164,24 +1176,14 @@
var getter = function() {
// Stack is still a raw array awaiting to be formatted.
var result = FormatStackTrace(obj, error_string,
GetStackFrames(stack));
- // Turn this accessor into a data property.
- %DefineOrRedefineDataProperty(obj, 'stack', result, NONE);
+ // Replace this accessor to return result directly.
+ %DefineOrRedefineAccessorProperty(
+ obj, 'stack', function() { return result }, setter, DONT_ENUM);
// Release context values.
stack = error_string = UNDEFINED;
return result;
};
- // Set the 'stack' property on the receiver. If the receiver is the
same as
- // holder of this setter, the accessor pair is turned into a data
property.
- var setter = function(v) {
- // Set data property on the receiver (not necessarily holder).
- %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
- if (this === obj) {
- // Release context values if holder is the same as the receiver.
- stack = error_string = UNDEFINED;
- }
- };
-
%DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter,
DONT_ENUM);
}
@@ -1320,6 +1322,15 @@
var error_string = boilerplate.name + ": " + boilerplate.message;
+ // Set the 'stack' property on the receiver. If the receiver is the
same as
+ // holder of this setter, the accessor pair is turned into a data
property.
+ var setter = function(v) {
+ %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
+ // Tentatively clear the hidden property. If the receiver is the same
as
+ // holder, we release the raw stack trace this way.
+ %GetAndClearOverflowedStackTrace(this);
+ };
+
// The raw stack trace is stored as a hidden property on the holder of
this
// getter, which may not be the same as the receiver. Find the holder to
// retrieve the raw stack trace and then turn this accessor pair into a
@@ -1335,20 +1346,12 @@
if (IS_UNDEFINED(stack)) return stack;
var result = FormatStackTrace(holder, error_string,
GetStackFrames(stack));
- // Replace this accessor with a data property.
- %DefineOrRedefineDataProperty(holder, 'stack', result, NONE);
+ // Replace this accessor to return result directly.
+ %DefineOrRedefineAccessorProperty(
+ holder, 'stack', function() { return result }, setter, DONT_ENUM);
return result;
};
- // Set the 'stack' property on the receiver. If the receiver is the
same as
- // holder of this setter, the accessor pair is turned into a data
property.
- var setter = function(v) {
- %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
- // Tentatively clear the hidden property. If the receiver is the same
as
- // holder, we release the raw stack trace this way.
- %GetAndClearOverflowedStackTrace(this);
- };
-
%DefineOrRedefineAccessorProperty(
boilerplate, 'stack', getter, setter, DONT_ENUM);
=======================================
--- /trunk/src/mips/code-stubs-mips.cc Mon Apr 28 16:21:24 2014 UTC
+++ /trunk/src/mips/code-stubs-mips.cc Tue Apr 29 00:04:31 2014 UTC
@@ -82,6 +82,11 @@
static Register registers[] = { a3, a2, a1 };
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers;
+ static Representation representations[] = {
+ Representation::Tagged(),
+ Representation::Smi(),
+ Representation::Tagged() };
+ descriptor->register_param_representations_ = representations;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry;
@@ -225,6 +230,11 @@
descriptor->stack_parameter_count_ = a0;
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers_variable_args;
+ static Representation representations[] = {
+ Representation::Tagged(),
+ Representation::Tagged(),
+ Representation::Integer32() };
+ descriptor->register_param_representations_ = representations;
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
@@ -252,6 +262,10 @@
descriptor->stack_parameter_count_ = a0;
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_variable_args;
+ static Representation representations[] = {
+ Representation::Tagged(),
+ Representation::Integer32() };
+ descriptor->register_param_representations_ = representations;
}
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
=======================================
--- /trunk/src/mips/full-codegen-mips.cc Mon Apr 28 16:21:24 2014 UTC
+++ /trunk/src/mips/full-codegen-mips.cc Tue Apr 29 00:04:31 2014 UTC
@@ -1850,17 +1850,7 @@
__ Push(a3, a2, a1, a0);
__ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4);
} else {
- ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
- FLAG_smi_only_arrays);
- FastCloneShallowArrayStub::Mode mode =
- FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
-
- if (has_fast_elements) {
- mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
- }
-
- FastCloneShallowArrayStub stub(isolate(), mode, allocation_site_mode,
- length);
+ FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
__ CallStub(&stub);
}
=======================================
--- /trunk/src/runtime.h Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/runtime.h Tue Apr 29 00:04:31 2014 UTC
@@ -97,7 +97,6 @@
F(SetNativeFlag, 1, 1) \
F(SetInlineBuiltinFlag, 1, 1) \
F(StoreArrayLiteralElement, 5, 1) \
- F(DebugCallbackSupportsStepping, 1, 1) \
F(DebugPrepareStepInIfStepping, 1, 1) \
F(DebugPendingExceptionInPromise, 2, 1) \
F(FlattenString, 1, 1) \
@@ -707,7 +706,9 @@
F(DoubleHi, 1,
1) \
F(DoubleLo, 1,
1) \
F(MathSqrt, 1,
1) \
- F(MathLog, 1, 1)
+ F(MathLog, 1,
1) \
+ /* Debugger
*/ \
+ F(DebugCallbackSupportsStepping, 1, 1)
//---------------------------------------------------------------------------
=======================================
--- /trunk/src/spaces.cc Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/spaces.cc Tue Apr 29 00:04:31 2014 UTC
@@ -2585,35 +2585,15 @@
allocation_info_.set_limit(NULL);
}
}
-
-
-bool PagedSpace::EnsureSweeperProgress(intptr_t size_in_bytes) {
- MarkCompactCollector* collector = heap()->mark_compact_collector();
- if (collector->AreSweeperThreadsActivated()) {
- if (collector->IsConcurrentSweepingInProgress()) {
- if (collector->RefillFreeLists(this) < size_in_bytes) {
- if (!collector->sequential_sweeping()) {
- collector->WaitUntilSweepingCompleted();
- return true;
- }
- }
- return false;
- }
- }
- return true;
-}
HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
// Allocation in this space has failed.
- // If there are unswept pages advance sweeping a bounded number of times
- // until we find a size_in_bytes contiguous piece of memory
- const int kMaxSweepingTries = 5;
- bool sweeping_complete = false;
-
- for (int i = 0; i < kMaxSweepingTries && !sweeping_complete; i++) {
- sweeping_complete = EnsureSweeperProgress(size_in_bytes);
+ // If sweeper threads are active, try to re-fill the free-lists.
+ MarkCompactCollector* collector = heap()->mark_compact_collector();
+ if (collector->IsConcurrentSweepingInProgress()) {
+ collector->RefillFreeList(this);
// Retry the free list allocation.
HeapObject* object = free_list_.Allocate(size_in_bytes);
@@ -2634,11 +2614,12 @@
return free_list_.Allocate(size_in_bytes);
}
- // Last ditch, sweep all the remaining pages to try to find space.
- if (heap()->mark_compact_collector()->IsConcurrentSweepingInProgress()) {
- heap()->mark_compact_collector()->WaitUntilSweepingCompleted();
+ // If sweeper threads are active, wait for them at that point.
+ if (collector->IsConcurrentSweepingInProgress()) {
+ collector->WaitUntilSweepingCompleted();
- // Retry the free list allocation.
+ // After waiting for the sweeper threads, there may be new free-list
+ // entries.
HeapObject* object = free_list_.Allocate(size_in_bytes);
if (object != NULL) return object;
}
=======================================
--- /trunk/src/spaces.h Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/src/spaces.h Tue Apr 29 00:04:31 2014 UTC
@@ -1913,12 +1913,6 @@
void ResetUnsweptFreeBytes() {
unswept_free_bytes_ = 0;
}
-
- // This function tries to steal size_in_bytes memory from the sweeper
threads
- // free-lists. If it does not succeed stealing enough memory, it will
wait
- // for the sweeper threads to finish sweeping.
- // It returns true when sweeping is completed and false otherwise.
- bool EnsureSweeperProgress(intptr_t size_in_bytes);
Page* FirstPage() { return anchor_.next_page(); }
Page* LastPage() { return anchor_.prev_page(); }
=======================================
--- /trunk/src/version.cc Mon Apr 28 16:21:24 2014 UTC
+++ /trunk/src/version.cc Tue Apr 29 00:04:31 2014 UTC
@@ -34,8 +34,8 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 26
-#define BUILD_NUMBER 26
-#define PATCH_LEVEL 1
+#define BUILD_NUMBER 27
+#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
=======================================
--- /trunk/test/cctest/test-debug.cc Mon Apr 28 00:05:12 2014 UTC
+++ /trunk/test/cctest/test-debug.cc Tue Apr 29 00:04:31 2014 UTC
@@ -7659,3 +7659,34 @@
v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
+
+
+static void DebugBreakStackTraceListener(
+ const v8::Debug::EventDetails& event_details) {
+ v8::StackTrace::CurrentStackTrace(CcTest::isolate(), 10);
+}
+
+
+static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args)
{
+ v8::Debug::DebugBreak(args.GetIsolate());
+}
+
+
+TEST(DebugBreakStackTrace) {
+ DebugLocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::Debug::SetDebugEventListener2(DebugBreakStackTraceListener);
+ v8::Handle<v8::FunctionTemplate> add_debug_break_template =
+ v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak);
+ v8::Handle<v8::Function> add_debug_break =
+ add_debug_break_template->GetFunction();
+ env->Global()->Set(v8_str("add_debug_break"), add_debug_break);
+
+ CompileRun("(function loop() {"
+ " for (var j = 0; j < 1000; j++) {"
+ " for (var i = 0; i < 1000; i++) {"
+ " if (i == 999) add_debug_break();"
+ " }"
+ " }"
+ "})()");
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.