Version 3.26.19 (based on bleeding_edge revision r20854)
ES6: Add support for Map/Set forEach (Chromium issues 1793, 2323).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@20864 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/accessors.cc b/src/accessors.cc
index 32c501a..76ec118 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -773,74 +773,55 @@
// Accessors::FunctionPrototype
//
-
-Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
- CALL_HEAP_FUNCTION(function->GetIsolate(),
- Accessors::FunctionGetPrototype(function->GetIsolate(),
- *function,
- NULL),
- Object);
-}
-
-
-Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
- Handle<Object> prototype) {
- ASSERT(function->should_have_prototype());
- CALL_HEAP_FUNCTION(function->GetIsolate(),
- Accessors::FunctionSetPrototype(function->GetIsolate(),
- *function,
- *prototype,
- NULL),
- Object);
-}
-
-
-MaybeObject* Accessors::FunctionGetPrototype(Isolate* isolate,
- Object* object,
- void*) {
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
- if (function_raw == NULL) return isolate->heap()->undefined_value();
- while (!function_raw->should_have_prototype()) {
- function_raw = FindInstanceOf<JSFunction>(isolate,
- function_raw->GetPrototype());
- // There has to be one because we hit the getter.
- ASSERT(function_raw != NULL);
+static Handle<Object> GetFunctionPrototype(Isolate* isolate,
+ Handle<Object> receiver) {
+ Handle<JSFunction> function;
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
+ if (function_raw == NULL) return isolate->factory()->undefined_value();
+ while (!function_raw->should_have_prototype()) {
+ function_raw = FindInstanceOf<JSFunction>(isolate,
+ function_raw->GetPrototype());
+ // There has to be one because we hit the getter.
+ ASSERT(function_raw != NULL);
+ }
+ function = Handle<JSFunction>(function_raw, isolate);
}
- if (!function_raw->has_prototype()) {
- HandleScope scope(isolate);
- Handle<JSFunction> function(function_raw);
+ if (!function->has_prototype()) {
Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
JSFunction::SetPrototype(function, proto);
- function_raw = *function;
}
- return function_raw->prototype();
+ return Handle<Object>(function->prototype(), isolate);
}
-MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
- JSObject* object_raw,
- Object* value_raw,
- void*) {
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object_raw);
- if (function_raw == NULL) return isolate->heap()->undefined_value();
+Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
+ return GetFunctionPrototype(function->GetIsolate(), function);
+}
- HandleScope scope(isolate);
- Handle<JSFunction> function(function_raw, isolate);
- Handle<JSObject> object(object_raw, isolate);
- Handle<Object> value(value_raw, isolate);
+
+
+MaybeHandle<Object> SetFunctionPrototype(Isolate* isolate,
+ Handle<JSObject> receiver,
+ Handle<Object> value) {
+ Handle<JSFunction> function;
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
+ if (function_raw == NULL) return isolate->factory()->undefined_value();
+ function = Handle<JSFunction>(function_raw, isolate);
+ }
+
if (!function->should_have_prototype()) {
// Since we hit this accessor, object will have no prototype property.
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::SetLocalPropertyIgnoreAttributes(
- object, isolate->factory()->prototype_string(), value, NONE));
- return *result;
+ return JSObject::SetLocalPropertyIgnoreAttributes(
+ receiver, isolate->factory()->prototype_string(), value, NONE);
}
Handle<Object> old_value;
- bool is_observed = *function == *object && function->map()->is_observed();
+ bool is_observed = *function == *receiver && function->map()->is_observed();
if (is_observed) {
if (function->has_prototype())
old_value = handle(function->prototype(), isolate);
@@ -856,7 +837,39 @@
function, "update", isolate->factory()->prototype_string(), old_value);
}
- return *function;
+ return function;
+}
+
+
+Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
+ Handle<Object> prototype) {
+ ASSERT(function->should_have_prototype());
+ Isolate* isolate = function->GetIsolate();
+ Handle<Object> result;
+ SetFunctionPrototype(isolate, function, prototype).ToHandle(&result);
+ return result;
+}
+
+
+MaybeObject* Accessors::FunctionGetPrototype(Isolate* isolate,
+ Object* object,
+ void*) {
+ HandleScope scope(isolate);
+ return *GetFunctionPrototype(isolate, Handle<Object>(object, isolate));
+}
+
+
+MaybeObject* Accessors::FunctionSetPrototype(Isolate* isolate,
+ JSObject* object,
+ Object* value,
+ void*) {
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ SetFunctionPrototype(isolate,
+ Handle<JSObject>(object, isolate),
+ Handle<Object>(value, isolate)));
+ return *result;
}
diff --git a/src/api.cc b/src/api.cc
index e88e91a..3550bb0 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -442,7 +442,7 @@
ResourceConstraints::ResourceConstraints()
- : max_young_space_size_(0),
+ : max_new_space_size_(0),
max_old_space_size_(0),
max_executable_size_(0),
stack_limit_(NULL),
@@ -452,7 +452,6 @@
void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
uint64_t virtual_memory_limit,
uint32_t number_of_processors) {
- const int lump_of_memory = (i::kPointerSize / 4) * i::MB;
#if V8_OS_ANDROID
// Android has higher physical memory requirements before raising the maximum
// heap size limits since it has no swap space.
@@ -465,24 +464,22 @@
const uint64_t high_limit = 1ul * i::GB;
#endif
- // The young_space_size should be a power of 2 and old_generation_size should
- // be a multiple of Page::kPageSize.
if (physical_memory <= low_limit) {
- set_max_young_space_size(2 * lump_of_memory);
- set_max_old_space_size(128 * lump_of_memory);
- set_max_executable_size(96 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeLowMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
} else if (physical_memory <= medium_limit) {
- set_max_young_space_size(8 * lump_of_memory);
- set_max_old_space_size(256 * lump_of_memory);
- set_max_executable_size(192 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeMediumMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
} else if (physical_memory <= high_limit) {
- set_max_young_space_size(16 * lump_of_memory);
- set_max_old_space_size(512 * lump_of_memory);
- set_max_executable_size(256 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeHighMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
} else {
- set_max_young_space_size(16 * lump_of_memory);
- set_max_old_space_size(700 * lump_of_memory);
- set_max_executable_size(256 * lump_of_memory);
+ set_max_new_space_size(i::Heap::kMaxNewSpaceSizeHugeMemoryDevice);
+ set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
+ set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
}
set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
@@ -499,15 +496,15 @@
bool SetResourceConstraints(Isolate* v8_isolate,
ResourceConstraints* constraints) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- int young_space_size = constraints->max_young_space_size();
+ int new_space_size = constraints->max_new_space_size();
int old_gen_size = constraints->max_old_space_size();
int max_executable_size = constraints->max_executable_size();
int code_range_size = constraints->code_range_size();
- if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0 ||
+ if (new_space_size != 0 || old_gen_size != 0 || max_executable_size != 0 ||
code_range_size != 0) {
// After initialization it's too late to change Heap constraints.
ASSERT(!isolate->IsInitialized());
- bool result = isolate->heap()->ConfigureHeap(young_space_size / 2,
+ bool result = isolate->heap()->ConfigureHeap(new_space_size / 2,
old_gen_size,
max_executable_size,
code_range_size);
@@ -3398,9 +3395,12 @@
name, getter, setter, data, settings, attributes, signature);
if (info.is_null()) return false;
bool fast = Utils::OpenHandle(obj)->HasFastProperties();
- i::Handle<i::Object> result =
- i::JSObject::SetAccessor(Utils::OpenHandle(obj), info);
- if (result.is_null() || result->IsUndefined()) return false;
+ i::Handle<i::Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, result,
+ i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
+ false);
+ if (result->IsUndefined()) return false;
if (fast) i::JSObject::TransformToFastProperties(Utils::OpenHandle(obj), 0);
return true;
}
@@ -5325,9 +5325,10 @@
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const char> string) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const char> string) {
if (type ==String::kInternalizedString) {
return factory->InternalizeUtf8String(string);
}
@@ -5335,9 +5336,10 @@
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const uint8_t> string) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const uint8_t> string) {
if (type == String::kInternalizedString) {
return factory->InternalizeOneByteString(string);
}
@@ -5345,9 +5347,10 @@
}
-inline i::Handle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
- i::Vector<const uint16_t> string) {
+MUST_USE_RESULT
+inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
+ String::NewStringType type,
+ i::Vector<const uint16_t> string) {
if (type == String::kInternalizedString) {
return factory->InternalizeTwoByteString(string);
}
@@ -5370,10 +5373,11 @@
}
ENTER_V8(isolate);
if (length == -1) length = StringLength(data);
- i::Handle<i::String> result = NewString(
- isolate->factory(), type, i::Vector<const Char>(data, length));
// We do not expect this to fail. Change this if it does.
- CHECK(!result.is_null());
+ i::Handle<i::String> result = NewString(
+ isolate->factory(),
+ type,
+ i::Vector<const Char>(data, length)).ToHandleChecked();
if (type == String::kUndetectableString) {
result->MarkAsUndetectable();
}
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index a3d740b..5525ec1 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -3842,211 +3842,6 @@
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = r0;
- Register scratch = r1;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ Ret();
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements = r6;
- Register end_elements = r5;
- // Get the elements array of the object.
- __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- scratch,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length into scratch and calculate new length.
- __ ldr(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ add(scratch, scratch, Operand(Smi::FromInt(argc)));
-
- // Get the elements' length.
- __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmp(scratch, r4);
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ b(gt, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
- __ JumpIfNotSmi(r4, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below, so
- // write back the value in end_elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
- } else {
- // Check if we could survive without allocation.
- __ cmp(scratch, r4);
- __ b(gt, &call_builtin);
-
- __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
- __ StoreNumberToDoubleElements(r4, scratch, elements, r5, d0,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ ldr(r9, FieldMemOperand(r4, HeapObject::kMapOffset));
- __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
- __ cmp(r9, ip);
- __ b(eq, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ ldr(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ ldr(r3, FieldMemOperand(r3, GlobalObject::kNativeContextOffset));
- __ ldr(r3, ContextOperand(r3, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ ldr(r2, FieldMemOperand(receiver, origin_offset));
- __ ldr(ip, FieldMemOperand(r3, HeapObject::kMapOffset));
- __ cmp(r2, ip);
- __ b(ne, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ ldr(r3, FieldMemOperand(r3, target_offset));
- __ mov(r2, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below, so write
- // back the value in end_elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
-
- __ RecordWrite(elements,
- end_elements,
- r4,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- __ bind(&attempt_to_grow_elements);
- // scratch: array's length + 1.
-
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(r2, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top and check if it is the end of elements.
- __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(scratch));
- __ add(end_elements, end_elements, Operand(kEndElementsOffset));
- __ mov(r4, Operand(new_space_allocation_top));
- __ ldr(r3, MemOperand(r4));
- __ cmp(end_elements, r3);
- __ b(ne, &call_builtin);
-
- __ mov(r9, Operand(new_space_allocation_limit));
- __ ldr(r9, MemOperand(r9));
- __ add(r3, r3, Operand(kAllocationDelta * kPointerSize));
- __ cmp(r3, r9);
- __ b(hi, &call_builtin);
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ str(r3, MemOperand(r4));
- // Push the argument.
- __ str(r2, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ str(r3, MemOperand(end_elements, i * kPointerSize));
- }
-
- // Update elements' and array's sizes.
- __ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta)));
- __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ Drop(argc + 1);
- __ mov(r0, scratch);
- __ Ret();
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r1 : left
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 6875dcf..3d07d56 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -430,13 +430,22 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -599,13 +608,22 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index 9bd2dca..a42f5cd 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -4405,215 +4405,6 @@
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = x0;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ Ldr(x0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Drop(argc + 1);
- __ Ret();
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements_length = x8;
- Register length = x7;
- Register elements = x6;
- Register end_elements = x5;
- Register value = x4;
- // Get the elements array of the object.
- __ Ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- x10,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length and calculate new length.
- __ Ldr(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- STATIC_ASSERT(kSmiTag == 0);
- __ Add(length, length, Smi::FromInt(argc));
-
- // Check if we could survive without allocation.
- __ Ldr(elements_length,
- FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Cmp(length, elements_length);
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ B(gt, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ Peek(value, (argc - 1) * kPointerSize);
- __ JumpIfNotSmi(value, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
- } else {
- __ B(gt, &call_builtin);
-
- __ Peek(value, (argc - 1) * kPointerSize);
- __ StoreNumberToDoubleElements(value, length, elements, x10, d0, d1,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Return length.
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ Bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ Bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) {
- __ B(&call_builtin);
- }
-
- __ Ldr(x10, FieldMemOperand(value, HeapObject::kMapOffset));
- __ JumpIfHeapNumber(x10, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ Ldr(x10, GlobalObjectMemOperand());
- __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kNativeContextOffset));
- __ Ldr(x10, ContextMemOperand(x10, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ ldr(x11, FieldMemOperand(receiver, origin_offset));
- __ ldr(x12, FieldMemOperand(x10, HeapObject::kMapOffset));
- __ cmp(x11, x12);
- __ B(ne, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ Ldr(x10, FieldMemOperand(x10, target_offset));
- __ Mov(x11, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
-
- __ RecordWrite(elements,
- end_elements,
- value,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- __ Bind(&attempt_to_grow_elements);
-
- if (!FLAG_inline_new) {
- __ B(&call_builtin);
- }
-
- Register argument = x2;
- __ Peek(argument, (argc - 1) * kPointerSize);
- // Growing elements that are SMI-only requires special handling in case
- // the new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(argument, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- Register allocation_top_addr = x5;
- Register allocation_top = x9;
- // Load top and check if it is the end of elements.
- __ Add(end_elements, elements,
- Operand::UntagSmiAndScale(length, kPointerSizeLog2));
- __ Add(end_elements, end_elements, kEndElementsOffset);
- __ Mov(allocation_top_addr, new_space_allocation_top);
- __ Ldr(allocation_top, MemOperand(allocation_top_addr));
- __ Cmp(end_elements, allocation_top);
- __ B(ne, &call_builtin);
-
- __ Mov(x10, new_space_allocation_limit);
- __ Ldr(x10, MemOperand(x10));
- __ Add(allocation_top, allocation_top, kAllocationDelta * kPointerSize);
- __ Cmp(allocation_top, x10);
- __ B(hi, &call_builtin);
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ Str(allocation_top, MemOperand(allocation_top_addr));
- // Push the argument.
- __ Str(argument, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
- ASSERT(kAllocationDelta == 4);
- __ Stp(x10, x10, MemOperand(end_elements, 1 * kPointerSize));
- __ Stp(x10, x10, MemOperand(end_elements, 3 * kPointerSize));
-
- // Update elements' and array's sizes.
- __ Str(length, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Add(elements_length, elements_length, Smi::FromInt(kAllocationDelta));
- __ Str(elements_length,
- FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ Drop(argc + 1);
- __ Mov(x0, length);
- __ Ret();
-
- __ Bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x1 : left
diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc
index bf12840..b46d813 100644
--- a/src/arm64/stub-cache-arm64.cc
+++ b/src/arm64/stub-cache-arm64.cc
@@ -392,13 +392,22 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
}
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
@@ -548,13 +557,22 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
}
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
diff --git a/src/array.js b/src/array.js
index ea4f3b4..a233c63 100644
--- a/src/array.js
+++ b/src/array.js
@@ -468,7 +468,13 @@
return ObservedArrayPush.apply(this, arguments);
for (var i = 0; i < m; i++) {
- this[i+n] = %_Arguments(i);
+ // Use SetProperty rather than a direct keyed store to ensure that the store
+ // site doesn't become poisened with an elements transition KeyedStoreIC.
+ //
+ // TODO(danno): Using %SetProperty is a temporary workaround. The spec says
+ // that ToObject needs to be called for primitive values (and
+ // Runtime_SetProperty seem to ignore them).
+ %SetProperty(this, i+n, %_Arguments(i), 0, kStrictMode);
}
var new_length = n + m;
diff --git a/src/ast.cc b/src/ast.cc
index b9e0b38..a1037f7 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1179,7 +1179,7 @@
} else {
str = DoubleToCString(value_->Number(), buffer);
}
- return isolate_->factory()->NewStringFromAscii(CStrVector(str));
+ return isolate_->factory()->NewStringFromAsciiChecked(str);
}
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 351d14a..d138910 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -484,17 +484,12 @@
// 262 15.3.4.
Handle<String> empty_string =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
+ Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction));
Handle<JSFunction> empty_function =
- factory->NewFunctionWithoutPrototype(empty_string, SLOPPY);
+ factory->NewFunctionWithoutPrototype(empty_string, code);
// --- E m p t y ---
- Handle<Code> code =
- Handle<Code>(isolate->builtins()->builtin(
- Builtins::kEmptyFunction));
- empty_function->set_code(*code);
- empty_function->shared()->set_code(*code);
- Handle<String> source =
- factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("() {}"));
+ Handle<String> source = factory->NewStringFromStaticAscii("() {}");
Handle<Script> script = factory->NewScript(source);
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
empty_function->shared()->set_script(*script);
@@ -567,16 +562,14 @@
if (throw_type_error_function.is_null()) {
Handle<String> name = factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("ThrowTypeError"));
- throw_type_error_function =
- factory()->NewFunctionWithoutPrototype(name, SLOPPY);
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kStrictModePoisonPill));
+ throw_type_error_function =
+ factory()->NewFunctionWithoutPrototype(name, code);
throw_type_error_function->set_map(native_context()->sloppy_function_map());
- throw_type_error_function->set_code(*code);
- throw_type_error_function->shared()->set_code(*code);
throw_type_error_function->shared()->DontAdaptArguments();
- JSObject::PreventExtensions(throw_type_error_function);
+ JSObject::PreventExtensions(throw_type_error_function).Assert();
}
return throw_type_error_function;
}
@@ -1404,10 +1397,12 @@
bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
Vector<const char> name = ExperimentalNatives::GetScriptName(index);
Factory* factory = isolate->factory();
- Handle<String> source_code =
+ Handle<String> source_code;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, source_code,
factory->NewStringFromAscii(
- ExperimentalNatives::GetRawScriptSource(index));
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, source_code, false);
+ ExperimentalNatives::GetRawScriptSource(index)),
+ false);
return CompileNative(isolate, name, source_code);
}
@@ -1456,8 +1451,8 @@
// function and insert it into the cache.
if (cache == NULL || !cache->Lookup(name, &function_info)) {
ASSERT(source->IsOneByteRepresentation());
- Handle<String> script_name = factory->NewStringFromUtf8(name);
- ASSERT(!script_name.is_null());
+ Handle<String> script_name =
+ factory->NewStringFromUtf8(name).ToHandleChecked();
function_info = Compiler::CompileScript(
source,
script_name,
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index 6dea116..f6fcd02 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -47,7 +47,8 @@
Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED);
cache_->CopyTo(0, *new_array, 0, cache_->length());
cache_ = *new_array;
- Handle<String> str = factory->NewStringFromAscii(name, TENURED);
+ Handle<String> str =
+ factory->NewStringFromAscii(name, TENURED).ToHandleChecked();
ASSERT(!str.is_null());
cache_->set(length, *str);
cache_->set(length + 1, *shared);
diff --git a/src/builtins.cc b/src/builtins.cc
index bfbc565..ad3691c 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -529,7 +529,7 @@
}
Handle<Object> element;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element, maybe_element);
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
accessor->SetLength(array, handle(Smi::FromInt(new_length), isolate)));
return *element;
@@ -1231,7 +1231,7 @@
result->VerifyApiCallResultType();
}
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (!is_construct || result->IsJSObject()) return result;
}
@@ -1301,7 +1301,7 @@
}
}
// Check for exceptions and return result.
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
diff --git a/src/code-stubs.h b/src/code-stubs.h
index ed08fcf..d8bb3ae 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -74,7 +74,6 @@
V(CEntry) \
V(JSEntry) \
V(KeyedLoadElement) \
- V(ArrayPush) \
V(ArrayNoArgumentConstructor) \
V(ArraySingleArgumentConstructor) \
V(ArrayNArgumentsConstructor) \
@@ -1165,30 +1164,6 @@
};
-class ArrayPushStub: public PlatformCodeStub {
- public:
- ArrayPushStub(ElementsKind kind, int argc) {
- bit_field_ = ElementsKindBits::encode(kind) | ArgcBits::encode(argc);
- }
-
- void Generate(MacroAssembler* masm);
-
- private:
- int arguments_count() { return ArgcBits::decode(bit_field_); }
- ElementsKind elements_kind() {
- return ElementsKindBits::decode(bit_field_);
- }
-
- virtual CodeStub::Major MajorKey() { return ArrayPush; }
- virtual int MinorKey() { return bit_field_; }
-
- class ElementsKindBits: public BitField<ElementsKind, 0, 3> {};
- class ArgcBits: public BitField<int, 3, Code::kArgumentsBits> {};
-
- int bit_field_;
-};
-
-
// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
// call support for stubs in Hydrogen.
class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub {
diff --git a/src/compiler.cc b/src/compiler.cc
index 3d64145..6978da4 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -866,11 +866,12 @@
}
-Handle<JSFunction> Compiler::GetFunctionFromEval(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- ParseRestriction restriction,
- int scope_position) {
+MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
+ Handle<String> source,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ ParseRestriction restriction,
+ int scope_position) {
Isolate* isolate = source->GetIsolate();
int source_length = source->length();
isolate->counters()->total_eval_size()->Increment(source_length);
@@ -898,7 +899,7 @@
shared_info = CompileToplevel(&info);
if (shared_info.is_null()) {
- return Handle<JSFunction>::null();
+ return MaybeHandle<JSFunction>();
} else {
// Explicitly disable optimization for eval code. We're not yet prepared
// to handle eval-code in the optimizing compiler.
diff --git a/src/compiler.h b/src/compiler.h
index 4bdb7ae..f16dd59 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -626,11 +626,12 @@
#endif
// Compile a String source within a context for eval.
- static Handle<JSFunction> GetFunctionFromEval(Handle<String> source,
- Handle<Context> context,
- StrictMode strict_mode,
- ParseRestriction restriction,
- int scope_position);
+ MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
+ Handle<String> source,
+ Handle<Context> context,
+ StrictMode strict_mode,
+ ParseRestriction restriction,
+ int scope_position);
// Compile a String source within a context.
static Handle<SharedFunctionInfo> CompileScript(
diff --git a/src/contexts.cc b/src/contexts.cc
index 5ee0d4b..d6866d0 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -365,11 +365,11 @@
Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
- Handle<Object> result(error_message_for_code_gen_from_strings(),
- GetIsolate());
+ Isolate* isolate = GetIsolate();
+ Handle<Object> result(error_message_for_code_gen_from_strings(), isolate);
if (!result->IsUndefined()) return result;
- return GetIsolate()->factory()->NewStringFromOneByte(STATIC_ASCII_VECTOR(
- "Code generation from strings disallowed for this context"));
+ return isolate->factory()->NewStringFromStaticAscii(
+ "Code generation from strings disallowed for this context");
}
diff --git a/src/d8.cc b/src/d8.cc
index 4e14cd5..99be861 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -982,7 +982,7 @@
factory->NewFixedArray(js_args.argc);
for (int j = 0; j < js_args.argc; j++) {
i::Handle<i::String> arg =
- factory->NewStringFromUtf8(i::CStrVector(js_args[j]));
+ factory->NewStringFromUtf8(i::CStrVector(js_args[j])).ToHandleChecked();
arguments_array->set(j, *arg);
}
i::Handle<i::JSArray> arguments_jsarray =
diff --git a/src/debug.cc b/src/debug.cc
index 4c53e19..c2d324e 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -753,8 +753,8 @@
Handle<String> source_code =
isolate->bootstrapper()->NativesSourceLookup(index);
Vector<const char> name = Natives::GetScriptName(index);
- Handle<String> script_name = factory->NewStringFromAscii(name);
- ASSERT(!script_name.is_null());
+ Handle<String> script_name =
+ factory->NewStringFromAscii(name).ToHandleChecked();
Handle<Context> context = isolate->native_context();
// Compile the script.
diff --git a/src/factory.cc b/src/factory.cc
index 9bcbf01..4db04d0 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -32,6 +32,16 @@
}
+Handle<HeapObject> Factory::NewFillerObject(int size,
+ bool double_align,
+ AllocationSpace space) {
+ CALL_HEAP_FUNCTION(
+ isolate(),
+ isolate()->heap()->AllocateFillerObject(size, double_align, space),
+ HeapObject);
+}
+
+
Handle<Box> Factory::NewBox(Handle<Object> value) {
Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE));
result->set_value(*value);
@@ -271,16 +281,29 @@
SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key);
-Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
- PretenureFlag pretenure) {
- CALL_HEAP_FUNCTION(
+MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
+ PretenureFlag pretenure) {
+ int length = string.length();
+ if (length == 1) {
+ return LookupSingleCharacterStringFromCode(string[0]);
+ }
+ Handle<SeqOneByteString> result;
+ ASSIGN_RETURN_ON_EXCEPTION(
isolate(),
- isolate()->heap()->AllocateStringFromOneByte(string, pretenure),
+ result,
+ NewRawOneByteString(string.length(), pretenure),
String);
+
+ DisallowHeapAllocation no_gc;
+ // Copy the characters into the new object.
+ CopyChars(SeqOneByteString::cast(*result)->GetChars(),
+ string.start(),
+ length);
+ return result;
}
-Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
- PretenureFlag pretenure) {
+MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
+ PretenureFlag pretenure) {
// Check for ASCII first since this is the common case.
const char* start = string.start();
int length = string.length();
@@ -300,8 +323,8 @@
}
-Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
- PretenureFlag pretenure) {
+MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
+ PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateStringFromTwoByte(string, pretenure),
@@ -975,35 +998,21 @@
}
-static Handle<Map> MapForNewFunction(Isolate *isolate,
- Handle<SharedFunctionInfo> function_info) {
- Context *context = isolate->context()->native_context();
- int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
- function_info->is_generator());
- return Handle<Map>(Map::cast(context->get(map_index)));
-}
-
-
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
- Handle<SharedFunctionInfo> function_info,
+ Handle<SharedFunctionInfo> info,
Handle<Context> context,
PretenureFlag pretenure) {
- Handle<JSFunction> result = NewFunctionHelper(
- MapForNewFunction(isolate(), function_info),
- function_info,
- the_hole_value(),
- pretenure);
+ Handle<JSFunction> result = NewFunction(
+ info, context, the_hole_value(), pretenure);
- if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
- function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
+ if (info->ic_age() != isolate()->heap()->global_ic_age()) {
+ info->ResetForNewContext(isolate()->heap()->global_ic_age());
}
- result->set_context(*context);
-
- int index = function_info->SearchOptimizedCodeMap(context->native_context(),
- BailoutId::None());
- if (!function_info->bound() && index < 0) {
- int number_of_literals = function_info->num_literals();
+ int index = info->SearchOptimizedCodeMap(context->native_context(),
+ BailoutId::None());
+ if (!info->bound() && index < 0) {
+ int number_of_literals = info->num_literals();
Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
if (number_of_literals > 0) {
// Store the native context in the literals array prefix. This
@@ -1017,10 +1026,9 @@
if (index > 0) {
// Caching of optimized code enabled and optimized code found.
- FixedArray* literals =
- function_info->GetLiteralsFromOptimizedCodeMap(index);
+ FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index);
if (literals != NULL) result->set_literals(literals);
- Code* code = function_info->GetCodeFromOptimizedCodeMap(index);
+ Code* code = info->GetCodeFromOptimizedCodeMap(index);
ASSERT(!code->marked_for_deoptimization());
result->ReplaceCode(code);
return result;
@@ -1029,9 +1037,9 @@
if (isolate()->use_crankshaft() &&
FLAG_always_opt &&
result->is_compiled() &&
- !function_info->is_toplevel() &&
- function_info->allows_lazy_compilation() &&
- !function_info->optimization_disabled() &&
+ !info->is_toplevel() &&
+ info->allows_lazy_compilation() &&
+ !info->optimization_disabled() &&
!isolate()->DebuggerHasBreakPoints()) {
result->MarkForOptimization();
}
@@ -1198,8 +1206,7 @@
} else {
buffer[kBufferSize - 1] = '\0';
}
- Handle<String> error_string = NewStringFromUtf8(CStrVector(buffer), TENURED);
- return error_string;
+ return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked();
}
@@ -1319,17 +1326,6 @@
}
-Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
- Handle<Code> code) {
- Handle<JSFunction> function = NewFunctionWithoutPrototype(name, SLOPPY);
- function->shared()->set_code(*code);
- function->set_code(*code);
- ASSERT(!function->has_initial_map());
- ASSERT(!function->has_prototype());
- return function;
-}
-
-
Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
Handle<FixedArray> array = NewFixedArray(length, TENURED);
array->set_map_no_write_barrier(*scope_info_map());
@@ -1752,8 +1748,9 @@
if (type == JS_FUNCTION_TYPE) {
map->set_function_with_prototype(true);
Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
- InitializeFunction(js_function, shared.ToHandleChecked(), the_hole_value());
- js_function->set_context(isolate()->context()->native_context());
+ Handle<Context> context(isolate()->context()->native_context());
+ InitializeFunction(js_function, shared.ToHandleChecked(),
+ context, null_value());
}
// Put in filler if the new object is smaller than the old.
@@ -1956,7 +1953,7 @@
// We tenure the allocated string since it is referenced from the
// number-string cache which lives in the old space.
- Handle<String> js_string = NewStringFromOneByte(OneByteVector(str), TENURED);
+ Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED);
SetNumberStringCache(number, js_string);
return js_string;
}
@@ -1983,53 +1980,68 @@
void Factory::InitializeFunction(Handle<JSFunction> function,
- Handle<SharedFunctionInfo> shared,
- Handle<Object> prototype) {
- ASSERT(!prototype->IsMap());
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ MaybeHandle<Object> maybe_prototype) {
function->initialize_properties();
function->initialize_elements();
- function->set_shared(*shared);
- function->set_code(shared->code());
+ function->set_shared(*info);
+ function->set_code(info->code());
+ function->set_context(*context);
+ Handle<Object> prototype;
+ if (maybe_prototype.ToHandle(&prototype)) {
+ ASSERT(!prototype->IsMap());
+ } else {
+ prototype = the_hole_value();
+ }
function->set_prototype_or_initial_map(*prototype);
- function->set_context(*undefined_value());
function->set_literals_or_bindings(*empty_fixed_array());
function->set_next_function_link(*undefined_value());
}
-Handle<JSFunction> Factory::NewFunctionHelper(Handle<Map> function_map,
- Handle<SharedFunctionInfo> shared,
- Handle<Object> prototype,
- PretenureFlag pretenure) {
- AllocationSpace space =
- (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
- Handle<JSFunction> fun = New<JSFunction>(function_map, space);
- InitializeFunction(fun, shared, prototype);
- return fun;
+static Handle<Map> MapForNewFunction(Isolate* isolate,
+ Handle<SharedFunctionInfo> function_info,
+ MaybeHandle<Object> maybe_prototype) {
+ if (maybe_prototype.is_null()) {
+ return function_info->strict_mode() == SLOPPY
+ ? isolate->sloppy_function_without_prototype_map()
+ : isolate->strict_function_without_prototype_map();
+ }
+
+ Context* context = isolate->context()->native_context();
+ int map_index = Context::FunctionMapIndex(function_info->strict_mode(),
+ function_info->is_generator());
+ return Handle<Map>(Map::cast(context->get(map_index)));
+}
+
+
+Handle<JSFunction> Factory::NewFunction(Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ MaybeHandle<Object> maybe_prototype,
+ PretenureFlag pretenure) {
+ Handle<Map> map = MapForNewFunction(isolate(), info, maybe_prototype);
+ AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
+ Handle<JSFunction> result = New<JSFunction>(map, space);
+ InitializeFunction(result, info, context, maybe_prototype);
+ return result;
}
Handle<JSFunction> Factory::NewFunction(Handle<String> name,
Handle<Object> prototype) {
- Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
- Handle<JSFunction> fun = NewFunctionHelper(
- isolate()->sloppy_function_map(), function_share, prototype);
- fun->set_context(isolate()->context()->native_context());
- return fun;
+ Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
+ Handle<Context> context(isolate()->context()->native_context());
+ return NewFunction(info, context, prototype);
}
-Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
- Handle<String> name,
- StrictMode strict_mode) {
- Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
- Handle<Map> map = strict_mode == SLOPPY
- ? isolate()->sloppy_function_without_prototype_map()
- : isolate()->strict_function_without_prototype_map();
- Handle<JSFunction> fun =
- NewFunctionHelper(map, function_share, the_hole_value());
- fun->set_context(isolate()->context()->native_context());
- return fun;
+Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
+ Handle<Code> code) {
+ Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name);
+ info->set_code(*code);
+ Handle<Context> context(isolate()->context()->native_context());
+ return NewFunction(info, context, MaybeHandle<Object>());
}
@@ -2111,12 +2123,8 @@
break;
}
- Handle<JSFunction> result =
- NewFunction(Factory::empty_string(),
- type,
- instance_size,
- code,
- true);
+ Handle<JSFunction> result = NewFunction(
+ Factory::empty_string(), type, instance_size, code, true);
// Set length.
result->shared()->set_length(obj->length());
@@ -2228,7 +2236,7 @@
// Install accumulated static accessors
for (int i = 0; i < valid_descriptors; i++) {
Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)));
- JSObject::SetAccessor(result, accessor);
+ JSObject::SetAccessor(result, accessor).Assert();
}
ASSERT(result->shared()->IsApiFunction());
diff --git a/src/factory.h b/src/factory.h
index d52e66e..6ceb201 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -118,11 +118,28 @@
// two byte.
//
// ASCII strings are pretenured when used as keys in the SourceCodeCache.
- Handle<String> NewStringFromOneByte(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromOneByte(
Vector<const uint8_t> str,
PretenureFlag pretenure = NOT_TENURED);
+
+ template<size_t N>
+ inline Handle<String> NewStringFromStaticAscii(
+ const char (&str)[N],
+ PretenureFlag pretenure = NOT_TENURED) {
+ ASSERT(N == StrLength(str) + 1);
+ return NewStringFromOneByte(
+ STATIC_ASCII_VECTOR(str), pretenure).ToHandleChecked();
+ }
+
+ inline Handle<String> NewStringFromAsciiChecked(
+ const char* str,
+ PretenureFlag pretenure = NOT_TENURED) {
+ return NewStringFromOneByte(
+ OneByteVector(str), pretenure).ToHandleChecked();
+ }
+
// TODO(dcarney): remove this function.
- inline Handle<String> NewStringFromAscii(
+ MUST_USE_RESULT inline MaybeHandle<String> NewStringFromAscii(
Vector<const char> str,
PretenureFlag pretenure = NOT_TENURED) {
return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure);
@@ -130,11 +147,11 @@
// UTF8 strings are pretenured when used for regexp literal patterns and
// flags in the parser.
- Handle<String> NewStringFromUtf8(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromUtf8(
Vector<const char> str,
PretenureFlag pretenure = NOT_TENURED);
- Handle<String> NewStringFromTwoByte(
+ MUST_USE_RESULT MaybeHandle<String> NewStringFromTwoByte(
Vector<const uc16> str,
PretenureFlag pretenure = NOT_TENURED);
@@ -269,6 +286,10 @@
int instance_size,
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);
+ Handle<HeapObject> NewFillerObject(int size,
+ bool double_align,
+ AllocationSpace space);
+
Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
@@ -442,9 +463,6 @@
bool force_initial_map);
Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
- StrictMode strict_mode);
-
- Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> code);
// Create a serialized scope info.
@@ -633,19 +651,19 @@
Handle<AllocationSite> allocation_site);
// Initializes a function with a shared part and prototype.
- // Note: this code was factored out of NewFunctionHelper such that
- // other parts of the VM could use it. Specifically, a function that creates
- // instances of type JS_FUNCTION_TYPE benefit from the use of this function.
+ // Note: this code was factored out of NewFunction such that other parts of
+ // the VM could use it. Specifically, a function that creates instances of
+ // type JS_FUNCTION_TYPE benefit from the use of this function.
inline void InitializeFunction(Handle<JSFunction> function,
- Handle<SharedFunctionInfo> shared,
- Handle<Object> prototype);
+ Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ MaybeHandle<Object> maybe_prototype);
// Creates a function initialized with a shared part.
- inline Handle<JSFunction> NewFunctionHelper(
- Handle<Map> function_map,
- Handle<SharedFunctionInfo> shared,
- Handle<Object> prototype,
- PretenureFlag pretenure = TENURED);
+ inline Handle<JSFunction> NewFunction(Handle<SharedFunctionInfo> info,
+ Handle<Context> context,
+ MaybeHandle<Object> maybe_prototype,
+ PretenureFlag pretenure = TENURED);
// Create a new map cache.
Handle<MapCache> NewMapCache(int at_least_space_for);
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 0d0a6ff..a6dcf5b 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -123,15 +123,20 @@
// Platform-specific code size multiplier.
#if V8_TARGET_ARCH_IA32
static const int kCodeSizeMultiplier = 100;
+ static const int kBootCodeSizeMultiplier = 100;
#elif V8_TARGET_ARCH_X64
static const int kCodeSizeMultiplier = 162;
+ static const int kBootCodeSizeMultiplier = 140;
#elif V8_TARGET_ARCH_ARM
static const int kCodeSizeMultiplier = 142;
+ static const int kBootCodeSizeMultiplier = 110;
#elif V8_TARGET_ARCH_ARM64
// TODO(all): Copied ARM value. Check this is sensible for ARM64.
static const int kCodeSizeMultiplier = 142;
+ static const int kBootCodeSizeMultiplier = 110;
#elif V8_TARGET_ARCH_MIPS
static const int kCodeSizeMultiplier = 142;
+ static const int kBootCodeSizeMultiplier = 120;
#else
#error Unsupported target architecture.
#endif
diff --git a/src/heap.cc b/src/heap.cc
index f1a0bfa..0738ffb 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -81,6 +81,7 @@
// Will be 4 * reserved_semispace_size_ to ensure that young
// generation can be aligned to its size.
maximum_committed_(0),
+ old_space_growing_factor_(4),
survived_since_last_expansion_(0),
sweep_generation_(0),
always_allocate_scope_depth_(0),
@@ -2408,6 +2409,22 @@
}
+MaybeObject* Heap::AllocateFillerObject(int size,
+ bool double_align,
+ AllocationSpace space) {
+ HeapObject* allocation;
+ { MaybeObject* maybe_allocation = AllocateRaw(size, space, space);
+ if (!maybe_allocation->To(&allocation)) return maybe_allocation;
+ }
+#ifdef DEBUG
+ MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
+ ASSERT(chunk->owner()->identity() == space);
+#endif
+ CreateFillerObjectAt(allocation->address(), size);
+ return allocation;
+}
+
+
MaybeObject* Heap::AllocatePolymorphicCodeCache() {
return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE);
}
@@ -3932,26 +3949,6 @@
}
-MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
- PretenureFlag pretenure) {
- int length = string.length();
- if (length == 1) {
- return Heap::LookupSingleCharacterStringFromCode(string[0]);
- }
- Object* result;
- { MaybeObject* maybe_result =
- AllocateRawOneByteString(string.length(), pretenure);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
-
- // Copy the characters into the new object.
- CopyChars(SeqOneByteString::cast(result)->GetChars(),
- string.start(),
- length);
- return result;
-}
-
-
MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
int non_ascii_start,
PretenureFlag pretenure) {
@@ -5309,6 +5306,12 @@
code_range_size_ = code_range_size;
+ // We set the old generation growing factor to 2 to grow the heap slower on
+ // memory-constrained devices.
+ if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
+ old_space_growing_factor_ = 2;
+ }
+
configured_ = true;
return true;
}
diff --git a/src/heap.h b/src/heap.h
index e4e8941..e8fdafb 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -348,7 +348,6 @@
"KeyedStoreElementMonomorphic") \
V(stack_overflow_string, "kStackOverflowBoilerplate") \
V(illegal_access_string, "illegal access") \
- V(illegal_execution_state_string, "illegal execution state") \
V(get_string, "get") \
V(set_string, "set") \
V(map_field_string, "%map") \
@@ -755,6 +754,12 @@
MUST_USE_RESULT MaybeObject* AllocatePartialMap(InstanceType instance_type,
int instance_size);
+ // Allocate a block of memory in the given space (filled with a filler).
+ // Used as a fall-back for generated code when the space is full.
+ MUST_USE_RESULT MaybeObject* AllocateFillerObject(int size,
+ bool double_align,
+ AllocationSpace space);
+
// Allocates an empty PolymorphicCodeCache.
MUST_USE_RESULT MaybeObject* AllocatePolymorphicCodeCache();
@@ -785,9 +790,6 @@
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
- MUST_USE_RESULT MaybeObject* AllocateStringFromOneByte(
- Vector<const uint8_t> str,
- PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT MaybeObject* AllocateStringFromUtf8Slow(
Vector<const char> str,
int non_ascii_start,
@@ -991,15 +993,6 @@
// data and clearing the resource pointer.
inline void FinalizeExternalString(String* string);
- // Allocates an uninitialized object. The memory is non-executable if the
- // hardware and OS allow.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this function does not perform a garbage collection.
- MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes,
- AllocationSpace space,
- AllocationSpace retry_space);
-
// Initialize a filler object to keep the ability to iterate over the heap
// when shortening objects.
void CreateFillerObjectAt(Address addr, int size);
@@ -1381,9 +1374,30 @@
static const intptr_t kMinimumOldGenerationAllocationLimit =
8 * (Page::kPageSize > MB ? Page::kPageSize : MB);
+ static const int kLumpOfMemory = (i::kPointerSize / 4) * i::MB;
+
+ // The new space size has to be a power of 2.
+ static const int kMaxNewSpaceSizeLowMemoryDevice = 2 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeMediumMemoryDevice = 8 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeHighMemoryDevice = 16 * kLumpOfMemory;
+ static const int kMaxNewSpaceSizeHugeMemoryDevice = 16 * kLumpOfMemory;
+
+ // The old space size has to be a multiple of Page::kPageSize.
+ static const int kMaxOldSpaceSizeLowMemoryDevice = 128 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeMediumMemoryDevice = 256 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeHighMemoryDevice = 512 * kLumpOfMemory;
+ static const int kMaxOldSpaceSizeHugeMemoryDevice = 700 * kLumpOfMemory;
+
+ // The executable size has to be a multiple of Page::kPageSize.
+ static const int kMaxExecutableSizeLowMemoryDevice = 128 * kLumpOfMemory;
+ static const int kMaxExecutableSizeMediumMemoryDevice = 256 * kLumpOfMemory;
+ static const int kMaxExecutableSizeHighMemoryDevice = 512 * kLumpOfMemory;
+ static const int kMaxExecutableSizeHugeMemoryDevice = 700 * kLumpOfMemory;
+
intptr_t OldGenerationAllocationLimit(intptr_t old_gen_size) {
- intptr_t limit = FLAG_stress_compaction ?
- old_gen_size + old_gen_size / 10 : old_gen_size * 4;
+ intptr_t limit = FLAG_stress_compaction
+ ? old_gen_size + old_gen_size / 10
+ : old_gen_size * old_space_growing_factor_;
limit = Max(limit, kMinimumOldGenerationAllocationLimit);
limit += new_space_.Capacity();
intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
@@ -1744,6 +1758,11 @@
intptr_t max_executable_size_;
intptr_t maximum_committed_;
+ // The old space growing factor is used in the old space heap growing
+ // strategy. The new old space size is the current old space size times
+ // old_space_growing_factor_.
+ int old_space_growing_factor_;
+
// For keeping track of how much data has survived
// scavenge since last new space expansion.
int survived_since_last_expansion_;
@@ -1970,6 +1989,14 @@
return (pretenure == TENURED) ? preferred_old_space : NEW_SPACE;
}
+ // Allocates an uninitialized object. The memory is non-executable if the
+ // hardware and OS allow. This is the single choke-point for allocations
+ // performed by the runtime and should not be bypassed (to extend this to
+ // inlined allocations, use the Heap::DisableInlineAllocation() support).
+ MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes,
+ AllocationSpace space,
+ AllocationSpace retry_space);
+
// Allocate an uninitialized fixed array.
MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(
int length, PretenureFlag pretenure);
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 833dc51..f3bd68f 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2621,6 +2621,15 @@
}
if (length > 0) {
+ // We have to initialize the elements pointer if allocation folding is
+ // turned off.
+ if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
+ HConstant* empty_fixed_array = Add<HConstant>(
+ isolate()->factory()->empty_fixed_array());
+ Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
+ empty_fixed_array, INITIALIZING_STORE);
+ }
+
HValue* boilerplate_elements = AddLoadElements(boilerplate);
HValue* object_elements;
if (IsFastDoubleElementsKind(kind)) {
@@ -7696,6 +7705,8 @@
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
ElementsKind elements_kind = receiver_map->elements_kind();
if (!IsFastElementsKind(elements_kind)) return false;
+ if (receiver_map->is_observed()) return false;
+ ASSERT(receiver_map->is_extensible());
Drop(expr->arguments()->length());
HValue* result;
@@ -7758,6 +7769,8 @@
if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
ElementsKind elements_kind = receiver_map->elements_kind();
if (!IsFastElementsKind(elements_kind)) return false;
+ if (receiver_map->is_observed()) return false;
+ ASSERT(receiver_map->is_extensible());
// If there may be elements accessors in the prototype chain, the fast
// inlined version can't be used.
@@ -7770,31 +7783,29 @@
Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
- HValue* op_vals[] = {
- context(),
- // Receiver.
- environment()->ExpressionStackAt(expr->arguments()->length())
- };
-
const int argc = expr->arguments()->length();
- // Includes receiver.
- PushArgumentsFromEnvironment(argc + 1);
+ if (argc != 1) return false;
- CallInterfaceDescriptor* descriptor =
- isolate()->call_descriptor(Isolate::CallHandler);
+ HValue* value_to_push = Pop();
+ HValue* array = Pop();
- ArrayPushStub stub(receiver_map->elements_kind(), argc);
- Handle<Code> code = stub.GetCode(isolate());
- HConstant* code_value = Add<HConstant>(code);
+ HValue* length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL),
+ HObjectAccess::ForArrayLength(elements_kind));
- ASSERT((sizeof(op_vals) / kPointerSize) ==
- descriptor->environment_length());
+ {
+ NoObservableSideEffectsScope scope(this);
- HInstruction* call = New<HCallWithDescriptor>(
- code_value, argc + 1, descriptor,
- Vector<HValue*>(op_vals, descriptor->environment_length()));
+ bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
+ BuildUncheckedMonomorphicElementAccess(array, length,
+ value_to_push, is_array,
+ elements_kind, STORE,
+ NEVER_RETURN_HOLE,
+ STORE_AND_GROW_NO_TRANSITION);
+ }
+
+ HInstruction* new_size = NewUncasted<HAdd>(length, Add<HConstant>(argc));
Drop(1); // Drop function.
- ast_context()->ReturnInstruction(call, expr->id());
+ ast_context()->ReturnInstruction(new_size, expr->id());
return true;
}
default:
diff --git a/src/i18n.cc b/src/i18n.cc
index bfe4200..c3f9541 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -57,7 +57,7 @@
Handle<JSObject> options,
const char* key,
icu::UnicodeString* setting) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
if (object->IsString()) {
v8::String::Utf8Value utf8_string(
@@ -73,7 +73,7 @@
Handle<JSObject> options,
const char* key,
int32_t* value) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
if (object->IsNumber()) {
object->ToInt32(value);
@@ -87,7 +87,7 @@
Handle<JSObject> options,
const char* key,
bool* value) {
- Handle<String> str = isolate->factory()->NewStringFromAscii(CStrVector(key));
+ Handle<String> str = isolate->factory()->NewStringFromAsciiChecked(key);
Handle<Object> object = Object::GetProperty(options, str).ToHandleChecked();
if (object->IsBoolean()) {
*value = object->BooleanValue();
@@ -149,16 +149,17 @@
const icu::Locale& icu_locale,
icu::SimpleDateFormat* date_format,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString pattern;
date_format->toPattern(pattern);
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("pattern"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
- pattern.length())),
+ pattern.length())).ToHandleChecked(),
NONE,
SLOPPY).Assert();
@@ -167,8 +168,8 @@
const char* calendar_name = calendar->getType();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("calendar")),
- isolate->factory()->NewStringFromAscii(CStrVector(calendar_name)),
+ factory->NewStringFromStaticAscii("calendar"),
+ factory->NewStringFromAsciiChecked(calendar_name),
NONE,
SLOPPY).Assert();
@@ -182,19 +183,19 @@
if (canonical_time_zone == UNICODE_STRING_SIMPLE("Etc/GMT")) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
- isolate->factory()->NewStringFromAscii(CStrVector("UTC")),
+ factory->NewStringFromStaticAscii("timeZone"),
+ factory->NewStringFromStaticAscii("UTC"),
NONE,
SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("timeZone")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("timeZone"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(
canonical_time_zone.getBuffer()),
- canonical_time_zone.length())),
+ canonical_time_zone.length())).ToHandleChecked(),
NONE,
SLOPPY).Assert();
}
@@ -210,15 +211,15 @@
const char* ns = numbering_system->getName();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->NewStringFromAscii(CStrVector(ns)),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->NewStringFromAsciiChecked(ns),
NONE,
SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->undefined_value(),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->undefined_value(),
NONE,
SLOPPY).Assert();
}
@@ -232,16 +233,16 @@
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
SLOPPY).Assert();
}
@@ -376,15 +377,16 @@
const icu::Locale& icu_locale,
icu::DecimalFormat* number_format,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
icu::UnicodeString pattern;
number_format->toPattern(pattern);
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("pattern")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("pattern"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(pattern.getBuffer()),
- pattern.length())),
+ pattern.length())).ToHandleChecked(),
NONE,
SLOPPY).Assert();
@@ -393,11 +395,11 @@
if (!currency.isEmpty()) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("currency")),
- isolate->factory()->NewStringFromTwoByte(
+ factory->NewStringFromStaticAscii("currency"),
+ factory->NewStringFromTwoByte(
Vector<const uint16_t>(
reinterpret_cast<const uint16_t*>(currency.getBuffer()),
- currency.length())),
+ currency.length())).ToHandleChecked(),
NONE,
SLOPPY).Assert();
}
@@ -412,15 +414,15 @@
const char* ns = numbering_system->getName();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->NewStringFromAscii(CStrVector(ns)),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->NewStringFromAsciiChecked(ns),
NONE,
SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numberingSystem")),
- isolate->factory()->undefined_value(),
+ factory->NewStringFromStaticAscii("numberingSystem"),
+ factory->undefined_value(),
NONE,
SLOPPY).Assert();
}
@@ -428,60 +430,49 @@
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("useGrouping")),
- isolate->factory()->ToBoolean(number_format->isGroupingUsed()),
+ factory->NewStringFromStaticAscii("useGrouping"),
+ factory->ToBoolean(number_format->isGroupingUsed()),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumIntegerDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumIntegerDigits()),
+ factory->NewStringFromStaticAscii("minimumIntegerDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumIntegerDigits()),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumFractionDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumFractionDigits()),
+ factory->NewStringFromStaticAscii("minimumFractionDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumFractionDigits()),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("maximumFractionDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMaximumFractionDigits()),
+ factory->NewStringFromStaticAscii("maximumFractionDigits"),
+ factory->NewNumberFromInt(number_format->getMaximumFractionDigits()),
NONE,
SLOPPY).Assert();
- Handle<String> key = isolate->factory()->NewStringFromAscii(
- CStrVector("minimumSignificantDigits"));
+ Handle<String> key =
+ factory->NewStringFromStaticAscii("minimumSignificantDigits");
if (JSReceiver::HasLocalProperty(resolved, key)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("minimumSignificantDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMinimumSignificantDigits()),
+ factory->NewStringFromStaticAscii("minimumSignificantDigits"),
+ factory->NewNumberFromInt(number_format->getMinimumSignificantDigits()),
NONE,
SLOPPY).Assert();
}
- key = isolate->factory()->NewStringFromAscii(
- CStrVector("maximumSignificantDigits"));
+ key = factory->NewStringFromStaticAscii("maximumSignificantDigits");
if (JSReceiver::HasLocalProperty(resolved, key)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(
- CStrVector("maximumSignificantDigits")),
- isolate->factory()->NewNumberFromInt(
- number_format->getMaximumSignificantDigits()),
+ factory->NewStringFromStaticAscii("maximumSignificantDigits"),
+ factory->NewNumberFromInt(number_format->getMaximumSignificantDigits()),
NONE,
SLOPPY).Assert();
}
@@ -494,16 +485,16 @@
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
SLOPPY).Assert();
}
@@ -578,12 +569,13 @@
const icu::Locale& icu_locale,
icu::Collator* collator,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("numeric")),
- isolate->factory()->ToBoolean(
+ factory->NewStringFromStaticAscii("numeric"),
+ factory->ToBoolean(
collator->getAttribute(UCOL_NUMERIC_COLLATION, status) == UCOL_ON),
NONE,
SLOPPY).Assert();
@@ -592,24 +584,24 @@
case UCOL_LOWER_FIRST:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("lower")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("lower"),
NONE,
SLOPPY).Assert();
break;
case UCOL_UPPER_FIRST:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("upper")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("upper"),
NONE,
SLOPPY).Assert();
break;
default:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("caseFirst")),
- isolate->factory()->NewStringFromAscii(CStrVector("false")),
+ factory->NewStringFromStaticAscii("caseFirst"),
+ factory->NewStringFromStaticAscii("false"),
NONE,
SLOPPY).Assert();
}
@@ -618,8 +610,8 @@
case UCOL_PRIMARY: {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("primary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("primary"),
NONE,
SLOPPY).Assert();
@@ -627,15 +619,15 @@
if (UCOL_ON == collator->getAttribute(UCOL_CASE_LEVEL, status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("case")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("case"),
NONE,
SLOPPY).Assert();
} else {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("base")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("base"),
NONE,
SLOPPY).Assert();
}
@@ -644,28 +636,28 @@
case UCOL_SECONDARY:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("secondary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("secondary"),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("accent")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("accent"),
NONE,
SLOPPY).Assert();
break;
case UCOL_TERTIARY:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("tertiary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("tertiary"),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
SLOPPY).Assert();
break;
@@ -674,36 +666,36 @@
// put them into variant.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("quaternary")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("quaternary"),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
SLOPPY).Assert();
break;
default:
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("strength")),
- isolate->factory()->NewStringFromAscii(CStrVector("identical")),
+ factory->NewStringFromStaticAscii("strength"),
+ factory->NewStringFromStaticAscii("identical"),
NONE,
SLOPPY).Assert();
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("sensitivity")),
- isolate->factory()->NewStringFromAscii(CStrVector("variant")),
+ factory->NewStringFromStaticAscii("sensitivity"),
+ factory->NewStringFromStaticAscii("variant"),
NONE,
SLOPPY).Assert();
}
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("ignorePunctuation")),
- isolate->factory()->ToBoolean(collator->getAttribute(
+ factory->NewStringFromStaticAscii("ignorePunctuation"),
+ factory->ToBoolean(collator->getAttribute(
UCOL_ALTERNATE_HANDLING, status) == UCOL_SHIFTED),
NONE,
SLOPPY).Assert();
@@ -716,16 +708,16 @@
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
SLOPPY).Assert();
}
@@ -769,6 +761,7 @@
const icu::Locale& icu_locale,
icu::BreakIterator* break_iterator,
Handle<JSObject> resolved) {
+ Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
// Set the locale
@@ -779,16 +772,16 @@
if (U_SUCCESS(status)) {
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromAsciiChecked(result),
NONE,
SLOPPY).Assert();
} else {
// This would never happen, since we got the locale from ICU.
JSObject::SetProperty(
resolved,
- isolate->factory()->NewStringFromAscii(CStrVector("locale")),
- isolate->factory()->NewStringFromAscii(CStrVector("und")),
+ factory->NewStringFromStaticAscii("locale"),
+ factory->NewStringFromStaticAscii("und"),
NONE,
SLOPPY).Assert();
}
@@ -852,7 +845,7 @@
Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("dateFormat"));
+ isolate->factory()->NewStringFromStaticAscii("dateFormat");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::SimpleDateFormat*>(
obj->GetInternalField(0));
@@ -926,7 +919,7 @@
Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("numberFormat"));
+ isolate->factory()->NewStringFromStaticAscii("numberFormat");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::DecimalFormat*>(obj->GetInternalField(0));
}
@@ -981,8 +974,7 @@
icu::Collator* Collator::UnpackCollator(Isolate* isolate,
Handle<JSObject> obj) {
- Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("collator"));
+ Handle<String> key = isolate->factory()->NewStringFromStaticAscii("collator");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::Collator*>(obj->GetInternalField(0));
}
@@ -1041,7 +1033,7 @@
icu::BreakIterator* BreakIterator::UnpackBreakIterator(Isolate* isolate,
Handle<JSObject> obj) {
Handle<String> key =
- isolate->factory()->NewStringFromAscii(CStrVector("breakIterator"));
+ isolate->factory()->NewStringFromStaticAscii("breakIterator");
if (JSReceiver::HasLocalProperty(obj, key)) {
return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0));
}
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index dca7ae7..cdb3a81 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -3744,198 +3744,6 @@
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- int argc = arguments_count();
-
- if (argc == 0) {
- // Noop, return the length.
- __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
- __ ret((argc + 1) * kPointerSize);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- // Get the elements array of the object.
- __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
- isolate->factory()->fixed_array_map());
- __ j(not_equal, &call_builtin);
- }
-
- // Get the array's length into eax and calculate new length.
- __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
- STATIC_ASSERT(kSmiTagSize == 1);
- STATIC_ASSERT(kSmiTag == 0);
- __ add(eax, Immediate(Smi::FromInt(argc)));
-
- // Get the elements' length into ecx.
- __ mov(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmp(eax, ecx);
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ j(greater, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ mov(ecx, Operand(esp, argc * kPointerSize));
- __ JumpIfNotSmi(ecx, &with_write_barrier);
-
- // Store the value.
- __ mov(FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize),
- ecx);
- } else {
- __ j(greater, &call_builtin);
-
- __ mov(ecx, Operand(esp, argc * kPointerSize));
- __ StoreNumberToDoubleElements(
- ecx, edi, eax, ecx, xmm0, &call_builtin, true, argc * kDoubleSize);
- }
-
- // Save new length.
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
- __ ret((argc + 1) * kPointerSize);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
- isolate->factory()->heap_number_map());
- __ j(equal, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ mov(ebx, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
- __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
- __ mov(ebx, ContextOperand(ebx, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ mov(edi, FieldOperand(ebx, origin_offset));
- __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset));
- __ j(not_equal, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ mov(ebx, FieldOperand(ebx, target_offset));
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- // Restore edi used as a scratch register for the write barrier used while
- // setting the map.
- __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
- }
-
- // Save new length.
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
-
- // Store the value.
- __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ mov(Operand(edx, 0), ecx);
-
- __ RecordWrite(edi, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
-
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&attempt_to_grow_elements);
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ mov(ebx, Operand(esp, argc * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(ebx, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top.
- __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
-
- // Check if it's the end of elements.
- __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ cmp(edx, ecx);
- __ j(not_equal, &call_builtin);
- __ add(ecx, Immediate(kAllocationDelta * kPointerSize));
- __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
- __ j(above, &call_builtin);
-
- // We fit and could grow elements.
- __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
-
- // Push the argument...
- __ mov(Operand(edx, 0), ebx);
- // ... and fill the rest with holes.
- for (int i = 1; i < kAllocationDelta; i++) {
- __ mov(Operand(edx, i * kPointerSize),
- isolate->factory()->the_hole_value());
- }
-
- if (IsFastObjectElementsKind(elements_kind())) {
- // We know the elements array is in new space so we don't need the
- // remembered set, but we just pushed a value onto it so we may have to tell
- // the incremental marker to rescan the object that we just grew. We don't
- // need to worry about the holes because they are in old space and already
- // marked black.
- __ RecordWrite(edi, edx, ebx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
- }
-
- // Restore receiver to edx as finish sequence assumes it's here.
- __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
-
- // Increment element's and array's sizes.
- __ add(FieldOperand(edi, FixedArray::kLengthOffset),
- Immediate(Smi::FromInt(kAllocationDelta)));
-
- // NOTE: This only happen in new-space, where we don't care about the
- // black-byte-count on pages. Otherwise we should update that too if the
- // object is black.
-
- __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- edx : left
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 9c82692..b3bc71c 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -528,13 +528,21 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -705,13 +713,21 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
diff --git a/src/isolate.h b/src/isolate.h
index afebdf1..5dd4b4e 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -117,7 +117,7 @@
// of handles to the actual constants.
typedef ZoneList<Handle<Object> > ZoneObjectList;
-#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
+#define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate) \
do { \
Isolate* __isolate__ = (isolate); \
if (__isolate__->has_scheduled_exception()) { \
@@ -125,15 +125,7 @@
} \
} while (false)
-#define RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, T) \
- do { \
- Isolate* __isolate__ = (isolate); \
- if (__isolate__->has_scheduled_exception()) { \
- __isolate__->PromoteScheduledException(); \
- return Handle<T>::null(); \
- } \
- } while (false)
-
+// TODO(yangguo): Remove after we completely changed to MaybeHandles.
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
do { \
if ((call).is_null()) { \
@@ -142,12 +134,14 @@
} \
} while (false)
+// TODO(yangguo): Remove after we completely changed to MaybeHandles.
#define CHECK_NOT_EMPTY_HANDLE(isolate, call) \
do { \
ASSERT(!(isolate)->has_pending_exception()); \
CHECK(!(call).is_null()); \
} while (false)
+// TODO(yangguo): Remove after we completely changed to MaybeHandles.
#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 35b3996..5fa6cf4 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -95,10 +95,12 @@
}
-static inline void ThrowRegExpException(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> error_text,
- const char* message) {
+MUST_USE_RESULT
+static inline MaybeHandle<Object> ThrowRegExpException(
+ Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> error_text,
+ const char* message) {
Isolate* isolate = re->GetIsolate();
Factory* factory = isolate->factory();
Handle<FixedArray> elements = factory->NewFixedArray(2);
@@ -106,7 +108,7 @@
elements->set(1, *error_text);
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> regexp_err = factory->NewSyntaxError(message, array);
- isolate->Throw(*regexp_err);
+ return isolate->Throw<Object>(regexp_err);
}
@@ -167,9 +169,9 @@
// Generic RegExp methods. Dispatches to implementation specific methods.
-Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> flag_str) {
+MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flag_str) {
Isolate* isolate = re->GetIsolate();
Zone zone(isolate);
JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
@@ -192,11 +194,10 @@
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
&parse_result, &zone)) {
// Throw an exception if we fail to parse the pattern.
- ThrowRegExpException(re,
- pattern,
- parse_result.error,
- "malformed_regexp");
- return Handle<Object>::null();
+ return ThrowRegExpException(re,
+ pattern,
+ parse_result.error,
+ "malformed_regexp");
}
bool has_been_compiled = false;
@@ -212,8 +213,11 @@
parse_result.capture_count == 0) {
RegExpAtom* atom = parse_result.tree->AsAtom();
Vector<const uc16> atom_pattern = atom->data();
- Handle<String> atom_string =
- isolate->factory()->NewStringFromTwoByte(atom_pattern);
+ Handle<String> atom_string;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, atom_string,
+ isolate->factory()->NewStringFromTwoByte(atom_pattern),
+ Object);
if (!HasFewDifferentCharacters(atom_string)) {
AtomCompile(re, pattern, flags, atom_string);
has_been_compiled = true;
@@ -448,10 +452,10 @@
&zone)) {
// Throw an exception if we fail to parse the pattern.
// THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
- ThrowRegExpException(re,
- pattern,
- compile_data.error,
- "malformed_regexp");
+ USE(ThrowRegExpException(re,
+ pattern,
+ compile_data.error,
+ "malformed_regexp"));
return false;
}
RegExpEngine::CompilationResult result =
@@ -465,9 +469,8 @@
&zone);
if (result.error_message != NULL) {
// Unable to compile regexp.
- Handle<String> error_message =
- isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
- ASSERT(!error_message.is_null());
+ Handle<String> error_message = isolate->factory()->NewStringFromUtf8(
+ CStrVector(result.error_message)).ToHandleChecked();
CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
return false;
}
diff --git a/src/jsregexp.h b/src/jsregexp.h
index a0b526b..444c66f 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -69,9 +69,10 @@
// generic data and choice of implementation - as well as what
// the implementation wants to store in the data field.
// Returns false if compilation fails.
- static Handle<Object> Compile(Handle<JSRegExp> re,
- Handle<String> pattern,
- Handle<String> flags);
+ MUST_USE_RESULT static MaybeHandle<Object> Compile(
+ Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags);
// See ECMA-262 section 15.10.6.2.
// This function calls the garbage collector if necessary.
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 4a6fe73..d0eab5b 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1888,8 +1888,8 @@
DropActivationsInActiveThread(shared_info_array, result, do_drop);
if (error_message != NULL) {
// Add error message as an array extra element.
- Handle<String> str = isolate->factory()->NewStringFromAscii(
- CStrVector(error_message));
+ Handle<String> str =
+ isolate->factory()->NewStringFromAsciiChecked(error_message);
SetElementSloppy(result, len, str);
}
return result;
diff --git a/src/macros.py b/src/macros.py
index 0b69e6b..0035451 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -87,6 +87,10 @@
const kMinMonth = -10000000;
const kMaxMonth = 10000000;
+# Strict mode flags for passing to %SetProperty
+const kSloppyMode = 0;
+const kStrictMode = 1;
+
# Native cache ids.
const STRING_TO_REGEXP_CACHE_ID = 0;
@@ -97,7 +101,7 @@
# values of 'bar'.
macro IS_NULL(arg) = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
-macro IS_UNDEFINED(arg) = (typeof(arg) === 'undefined');
+macro IS_UNDEFINED(arg) = (arg === (void 0));
macro IS_NUMBER(arg) = (typeof(arg) === 'number');
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_BOOLEAN(arg) = (typeof(arg) === 'boolean');
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 750cf54..31851a2 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -4008,206 +4008,6 @@
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- Register receiver = a0;
- Register scratch = a1;
-
- int argc = arguments_count();
-
- if (argc == 0) {
- // Nothing to do, just return the length.
- __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ DropAndRet(argc + 1);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- Register elements = t2;
- Register end_elements = t1;
- // Get the elements array of the object.
- __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ CheckMap(elements,
- scratch,
- Heap::kFixedArrayMapRootIndex,
- &call_builtin,
- DONT_DO_SMI_CHECK);
- }
-
- // Get the array's length into scratch and calculate new length.
- __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ Addu(scratch, scratch, Operand(Smi::FromInt(argc)));
-
- // Get the elements' length.
- __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- const int kEndElementsOffset =
- FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check if we could survive without allocation.
- __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0));
-
- // Check if value is a smi.
- __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
- __ JumpIfNotSmi(t0, &with_write_barrier);
-
- // Store the value.
- // We may need a register containing the address end_elements below,
- // so write back the value in end_elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, kEndElementsOffset);
- __ sw(t0, MemOperand(end_elements));
- } else {
- // Check if we could survive without allocation.
- __ Branch(&call_builtin, gt, scratch, Operand(t0));
-
- __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
- __ StoreNumberToDoubleElements(t0, scratch, elements, a3, t1, a2,
- &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ lw(t3, FieldMemOperand(t0, HeapObject::kMapOffset));
- __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
- __ Branch(&call_builtin, eq, t3, Operand(at));
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ lw(a3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
- __ lw(a3, FieldMemOperand(a3, GlobalObject::kNativeContextOffset));
- __ lw(a3, ContextOperand(a3, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ lw(a2, FieldMemOperand(receiver, origin_offset));
- __ lw(at, FieldMemOperand(a3, HeapObject::kMapOffset));
- __ Branch(&call_builtin, ne, a2, Operand(at));
-
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ lw(a3, FieldMemOperand(a3, target_offset));
- __ mov(a2, receiver);
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- }
-
- // Save new length.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
-
- // Store the value.
- // We may need a register containing the address end_elements below, so write
- // back the value in end_elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, kEndElementsOffset);
- __ sw(t0, MemOperand(end_elements));
-
- __ RecordWrite(elements,
- end_elements,
- t0,
- kRAHasNotBeenSaved,
- kDontSaveFPRegs,
- EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- __ bind(&attempt_to_grow_elements);
- // scratch: array's length + 1.
-
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- if (IsFastSmiElementsKind(elements_kind())) {
- __ JumpIfNotSmi(a2, &call_builtin);
- }
-
- // We could be lucky and the elements array could be at the top of new-space.
- // In this case we can just grow it in place by moving the allocation pointer
- // up.
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top and check if it is the end of elements.
- __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(end_elements, elements, end_elements);
- __ Addu(end_elements, end_elements, Operand(kEndElementsOffset));
- __ li(t0, Operand(new_space_allocation_top));
- __ lw(a3, MemOperand(t0));
- __ Branch(&call_builtin, ne, a3, Operand(end_elements));
-
- __ li(t3, Operand(new_space_allocation_limit));
- __ lw(t3, MemOperand(t3));
- __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize));
- __ Branch(&call_builtin, hi, a3, Operand(t3));
-
- // We fit and could grow elements.
- // Update new_space_allocation_top.
- __ sw(a3, MemOperand(t0));
- // Push the argument.
- __ sw(a2, MemOperand(end_elements));
- // Fill the rest with holes.
- __ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ sw(a3, MemOperand(end_elements, i * kPointerSize));
- }
-
- // Update elements' and array's sizes.
- __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
- __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
- __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta)));
- __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
-
- // Elements are in new space, so write barrier is not required.
- __ mov(v0, scratch);
- __ DropAndRet(argc + 1);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a1 : left
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 2cd61f9..59dc905 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -415,13 +415,24 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ Handle<Map> current;
+ if (!it.Done()) {
+ __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ // Do the CompareMap() directly within the Branch() functions.
+ current = it.Current();
+ it.Advance();
+ if (it.Done()) {
+ __ Branch(miss_label, ne, scratch1, Operand(current));
+ break;
+ }
+ __ Branch(&do_store, eq, scratch1, Operand(current));
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -585,13 +596,24 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ Handle<Map> current;
+ while (true) {
+ // Do the CompareMap() directly within the Branch() functions.
+ current = it.Current();
+ it.Advance();
+ if (it.Done()) {
+ __ Branch(miss_label, ne, scratch1, Operand(current));
+ break;
+ }
+ __ Branch(&do_store, eq, scratch1, Operand(current));
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 40132cb..aa82614 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -300,13 +300,10 @@
if (r.IsSmi()) ASSERT(value->IsSmi());
if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
HeapType* field_type = descriptors->GetFieldType(i);
- if (field_type->IsClass()) {
- Map* map = *field_type->AsClass()->Map();
- CHECK(!map->is_stable() || HeapObject::cast(value)->map() == map);
- } else if (r.IsNone()) {
+ if (r.IsNone()) {
CHECK(field_type->Is(HeapType::None()));
- } else {
- CHECK(HeapType::Any()->Is(field_type));
+ } else if (!HeapType::Any()->Is(field_type)) {
+ CHECK(!field_type->NowStable() || field_type->NowContains(value));
}
}
}
diff --git a/src/objects.cc b/src/objects.cc
index 4a3b542..2a5e86b 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -63,15 +63,16 @@
Handle<HeapType> Object::OptimalType(Isolate* isolate,
Representation representation) {
- if (!FLAG_track_field_types) return HeapType::Any(isolate);
- if (representation.IsNone()) return HeapType::None(isolate);
- if (representation.IsHeapObject() && IsHeapObject()) {
- // We can track only JavaScript objects with stable maps.
- Handle<Map> map(HeapObject::cast(this)->map(), isolate);
- if (map->is_stable() &&
- map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
- map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
- return HeapType::Class(map, isolate);
+ if (FLAG_track_field_types) {
+ if (representation.IsNone()) return HeapType::None(isolate);
+ if (representation.IsHeapObject() && IsHeapObject()) {
+ // We can track only JavaScript objects with stable maps.
+ Handle<Map> map(HeapObject::cast(this)->map(), isolate);
+ if (map->is_stable() &&
+ map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+ map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
+ return HeapType::Class(map, isolate);
+ }
}
}
return HeapType::Any(isolate);
@@ -538,7 +539,7 @@
// No accessible property found.
*attributes = ABSENT;
isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
@@ -883,7 +884,7 @@
if (js_object->IsAccessCheckNeeded()) {
if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
}
@@ -2526,11 +2527,21 @@
// static
-Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type,
- Handle<HeapType> new_field_type,
+Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
Isolate* isolate) {
- if (new_field_type->NowIs(old_field_type)) return old_field_type;
- if (old_field_type->NowIs(new_field_type)) return new_field_type;
+ static const int kMaxClassesPerFieldType = 5;
+ if (type1->NowIs(type2)) return type2;
+ if (type2->NowIs(type1)) return type1;
+ if (type1->NowStable() && type2->NowStable()) {
+ Handle<HeapType> type = HeapType::Union(type1, type2, isolate);
+ if (type->NumClasses() <= kMaxClassesPerFieldType) {
+ ASSERT(type->NowStable());
+ ASSERT(type1->NowIs(type));
+ ASSERT(type2->NowIs(type));
+ return type;
+ }
+ }
return HeapType::Any(isolate);
}
@@ -5243,8 +5254,8 @@
}
-Handle<Object> JSObject::DeletePropertyWithInterceptor(Handle<JSObject> object,
- Handle<Name> name) {
+MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
+ Handle<JSObject> object, Handle<Name> name) {
Isolate* isolate = object->GetIsolate();
// TODO(rossberg): Support symbols in the API.
@@ -5260,7 +5271,7 @@
isolate, interceptor->data(), *object, *object);
v8::Handle<v8::Boolean> result =
args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
@@ -5271,7 +5282,6 @@
}
Handle<Object> result =
DeletePropertyPostInterceptor(object, name, NORMAL_DELETION);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
return result;
}
@@ -5295,7 +5305,7 @@
PropertyCallbackArguments args(
isolate, interceptor->data(), *object, *object);
v8::Handle<v8::Boolean> result = args.Call(deleter, index);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
ASSERT(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
@@ -5319,7 +5329,7 @@
if (object->IsAccessCheckNeeded() &&
!isolate->MayIndexedAccess(object, index, v8::ACCESS_DELETE)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->false_value();
}
@@ -5388,7 +5398,7 @@
if (object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5435,7 +5445,10 @@
if (mode == FORCE_DELETION) {
result = DeletePropertyPostInterceptor(object, name, mode);
} else {
- result = DeletePropertyWithInterceptor(object, name);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ DeletePropertyWithInterceptor(object, name),
+ Object);
}
} else {
// Normalize object if needed.
@@ -5610,7 +5623,7 @@
}
-Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
+MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
Isolate* isolate = object->GetIsolate();
if (!object->map()->is_extensible()) return object;
@@ -5619,7 +5632,7 @@
!isolate->MayNamedAccess(
object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->false_value();
}
@@ -5637,8 +5650,7 @@
isolate->factory()->NewTypeError(
"cant_prevent_ext_external_array_elements",
HandleVector(&object, 1));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
// If there are fast elements we normalize.
@@ -6921,8 +6933,8 @@
}
-Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
- Handle<AccessorInfo> info) {
+MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
+ Handle<AccessorInfo> info) {
Isolate* isolate = object->GetIsolate();
Factory* factory = isolate->factory();
Handle<Name> name(Name::cast(info->name()));
@@ -6931,7 +6943,7 @@
if (object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return factory->undefined_value();
}
@@ -7004,9 +7016,9 @@
}
-Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
- Handle<Name> name,
- AccessorComponent component) {
+MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object,
+ Handle<Name> name,
+ AccessorComponent component) {
Isolate* isolate = object->GetIsolate();
// Make sure that the top context does not change when doing callbacks or
@@ -7017,7 +7029,7 @@
if (object->IsAccessCheckNeeded() &&
!isolate->MayNamedAccess(object, name, v8::ACCESS_HAS)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
return isolate->factory()->undefined_value();
}
@@ -8030,41 +8042,27 @@
}
-void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache,
+void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache,
MapHandleList* maps,
Code::Flags flags,
Handle<Code> code) {
- Isolate* isolate = cache->GetIsolate();
- CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code));
-}
-
-
-MaybeObject* PolymorphicCodeCache::Update(MapHandleList* maps,
- Code::Flags flags,
- Code* code) {
- // Initialize cache if necessary.
- if (cache()->IsUndefined()) {
- Object* result;
- { MaybeObject* maybe_result =
- PolymorphicCodeCacheHashTable::Allocate(
- GetHeap(),
- PolymorphicCodeCacheHashTable::kInitialSize);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- set_cache(result);
+ Isolate* isolate = code_cache->GetIsolate();
+ if (code_cache->cache()->IsUndefined()) {
+ Handle<PolymorphicCodeCacheHashTable> result =
+ PolymorphicCodeCacheHashTable::New(
+ isolate,
+ PolymorphicCodeCacheHashTable::kInitialSize);
+ code_cache->set_cache(*result);
} else {
// This entry shouldn't be contained in the cache yet.
- ASSERT(PolymorphicCodeCacheHashTable::cast(cache())
+ ASSERT(PolymorphicCodeCacheHashTable::cast(code_cache->cache())
->Lookup(maps, flags)->IsUndefined());
}
- PolymorphicCodeCacheHashTable* hash_table =
- PolymorphicCodeCacheHashTable::cast(cache());
- Object* new_cache;
- { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code);
- if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
- }
- set_cache(new_cache);
- return this;
+ Handle<PolymorphicCodeCacheHashTable> hash_table =
+ handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache()));
+ Handle<PolymorphicCodeCacheHashTable> new_cache =
+ PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code);
+ code_cache->set_cache(*new_cache);
}
@@ -8086,8 +8084,10 @@
class PolymorphicCodeCacheHashTableKey : public HashTableKey {
public:
// Callers must ensure that |maps| outlives the newly constructed object.
- PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags)
- : maps_(maps),
+ PolymorphicCodeCacheHashTableKey(
+ Isolate* isolate, MapHandleList* maps, int code_flags)
+ : isolate_(isolate),
+ maps_(maps),
code_flags_(code_flags) {}
bool IsMatch(Object* other) {
@@ -8153,6 +8153,12 @@
return list;
}
+ Handle<FixedArray> AsHandle() {
+ CALL_HEAP_FUNCTION(isolate_,
+ AsObject(isolate_->heap()),
+ FixedArray);
+ }
+
private:
static MapHandleList* FromObject(Object* obj,
int* code_flags,
@@ -8166,6 +8172,7 @@
return maps;
}
+ Isolate* isolate_;
MapHandleList* maps_; // weak.
int code_flags_;
static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1;
@@ -8173,30 +8180,29 @@
Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps,
- int code_flags) {
- PolymorphicCodeCacheHashTableKey key(maps, code_flags);
+ int code_kind) {
+ DisallowHeapAllocation no_alloc;
+ PolymorphicCodeCacheHashTableKey key(GetIsolate(), maps, code_kind);
int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1);
}
-MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps,
- int code_flags,
- Code* code) {
- PolymorphicCodeCacheHashTableKey key(maps, code_flags);
- Object* obj;
- { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- PolymorphicCodeCacheHashTable* cache =
- reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj);
+Handle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put(
+ Handle<PolymorphicCodeCacheHashTable> hash_table,
+ MapHandleList* maps,
+ int code_kind,
+ Handle<Code> code) {
+ PolymorphicCodeCacheHashTableKey key(
+ hash_table->GetIsolate(), maps, code_kind);
+ Handle<PolymorphicCodeCacheHashTable> cache =
+ EnsureCapacity(hash_table, 1, &key);
int entry = cache->FindInsertionEntry(key.Hash());
- { MaybeObject* maybe_obj = key.AsObject(GetHeap());
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- }
- cache->set(EntryToIndex(entry), obj);
- cache->set(EntryToIndex(entry) + 1, code);
+
+ Handle<FixedArray> obj = key.AsHandle();
+ cache->set(EntryToIndex(entry), *obj);
+ cache->set(EntryToIndex(entry) + 1, *code);
cache->ElementAdded();
return cache;
}
@@ -13559,7 +13565,7 @@
PropertyCallbackArguments
args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Value> result = args.Call(getter, index);
- RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (!result.IsEmpty()) {
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
diff --git a/src/objects.h b/src/objects.h
index 831e013..bf6dd6b 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2364,9 +2364,10 @@
// Retrieves an AccessorPair property from the given object. Might return
// undefined if the property doesn't exist or is of a different kind.
- static Handle<Object> GetAccessor(Handle<JSObject> object,
- Handle<Name> name,
- AccessorComponent component);
+ MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ AccessorComponent component);
// Defines an AccessorPair property on the given object.
// TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
@@ -2379,8 +2380,9 @@
v8::AccessControl access_control = v8::DEFAULT);
// Defines an AccessorInfo property on the given object.
- static Handle<Object> SetAccessor(Handle<JSObject> object,
- Handle<AccessorInfo> info);
+ MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
+ Handle<JSObject> object,
+ Handle<AccessorInfo> info);
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Handle<JSObject> object,
@@ -2658,7 +2660,8 @@
bool ReferencesObject(Object* obj);
// Disalow further properties to be added to the object.
- static Handle<Object> PreventExtensions(Handle<JSObject> object);
+ MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
+ Handle<JSObject> object);
// ES5 Object.freeze
MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
@@ -2938,8 +2941,9 @@
static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
- static Handle<Object> DeletePropertyWithInterceptor(Handle<JSObject> object,
- Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Name> name);
// Deletes the named property in a normalized object.
static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
@@ -6252,8 +6256,8 @@
int target_inobject,
int target_unused);
static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
- static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> old_field_type,
- Handle<HeapType> new_field_type,
+ static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
Isolate* isolate)
V8_WARN_UNUSED_RESULT;
static void GeneralizeFieldType(Handle<Map> map,
@@ -8403,9 +8407,6 @@
Code::Flags flags,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps,
- Code::Flags flags,
- Code* code);
// Returns an undefined value if the entry is not found.
Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
@@ -8431,9 +8432,11 @@
public:
Object* Lookup(MapHandleList* maps, int code_kind);
- MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps,
- int code_kind,
- Code* code);
+ static Handle<PolymorphicCodeCacheHashTable> Put(
+ Handle<PolymorphicCodeCacheHashTable> hash_table,
+ MapHandleList* maps,
+ int code_kind,
+ Handle<Code> code);
static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
diff --git a/src/parser.cc b/src/parser.cc
index 9d37c88..c535704 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -683,8 +683,8 @@
Factory* factory = parser_->isolate()->factory();
Handle<FixedArray> elements = factory->NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
- ASSERT(!arg_string.is_null());
+ Handle<String> arg_string =
+ factory->NewStringFromUtf8(CStrVector(args[i])).ToHandleChecked();
elements->set(i, *arg_string);
}
Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
@@ -3842,8 +3842,8 @@
RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
failed_ = true;
- *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
- ASSERT(!error_->is_null());
+ *error_ = isolate()->factory()->NewStringFromAscii(
+ message, NOT_TENURED).ToHandleChecked();
// Zip to the end to make sure the no more input is read.
current_ = kEndMarker;
next_pos_ = in()->length();
diff --git a/src/preparser.h b/src/preparser.h
index de08eb3..ce8df77 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -2047,7 +2047,7 @@
Consume(Token::FUNCTION);
int function_token_position = position();
bool is_generator = allow_generators() && Check(Token::MUL);
- IdentifierT name;
+ IdentifierT name = this->EmptyIdentifier();
bool is_strict_reserved_name = false;
Scanner::Location function_name_location = Scanner::Location::invalid();
FunctionLiteral::FunctionType function_type =
diff --git a/src/runtime.cc b/src/runtime.cc
index 92dc782..b413642 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -105,6 +105,12 @@
#define RUNTIME_ASSERT(value) \
if (!(value)) return isolate->ThrowIllegalOperation();
+#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
+ if (!(value)) { \
+ isolate->ThrowIllegalOperation(); \
+ return MaybeHandle<T>(); \
+ }
+
// Cast the given object to a value of the specified type and store
// it in a variable with the given name. If the object is not of the
// expected type call IllegalOperation and return.
@@ -116,6 +122,10 @@
RUNTIME_ASSERT(args[index]->Is##Type()); \
Handle<Type> name = args.at<Type>(index);
+#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index) \
+ RUNTIME_ASSERT(args[index]->IsNumber()); \
+ Handle<Object> name = args.at<Object>(index);
+
// Cast the given object to a boolean and store it in a variable with
// the given name. If the object is not a boolean call IllegalOperation
// and return.
@@ -305,8 +315,7 @@
char arr[100];
Vector<char> buffer(arr, ARRAY_SIZE(arr));
const char* str = DoubleToCString(num, buffer);
- Handle<String> name =
- isolate->factory()->NewStringFromAscii(CStrVector(str));
+ Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
boilerplate, name, value, NONE,
Object::OPTIMAL_REPRESENTATION, mode);
@@ -483,6 +492,8 @@
bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
+ RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
+
// Check if boilerplate exists. If not, create it first.
Handle<Object> literal_site(literals->get(literals_index), isolate);
Handle<AllocationSite> site;
@@ -560,6 +571,8 @@
int literals_index,
Handle<FixedArray> elements,
int flags) {
+ RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
+ literals_index < literals->length(), JSObject);
Handle<AllocationSite> site;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, site,
@@ -614,7 +627,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> name = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
Handle<Symbol> symbol = isolate->factory()->NewSymbol();
if (name->IsString()) symbol->set_name(*name);
@@ -625,7 +638,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CreatePrivateSymbol) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> name = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
if (name->IsString()) symbol->set_name(*name);
@@ -691,7 +704,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
- Handle<Object> prototype = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
return *isolate->factory()->NewJSProxy(handler, prototype);
}
@@ -701,10 +714,10 @@
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
- Handle<Object> call_trap = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
- Handle<Object> prototype = args.at<Object>(3);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
return *isolate->factory()->NewJSFunctionProxy(
handler, call_trap, construct_trap, prototype);
@@ -714,7 +727,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSProxy());
}
@@ -722,7 +735,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
}
@@ -817,7 +830,7 @@
data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
} else {
data =
- V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
+ V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
}
if (data == NULL) return false;
} else {
@@ -854,32 +867,19 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
- size_t allocated_length;
- if (byteLength->IsSmi()) {
- allocated_length = Smi::cast(*byteLength)->value();
- } else {
- ASSERT(byteLength->IsHeapNumber());
- double value = HeapNumber::cast(*byteLength)->value();
-
- ASSERT(value >= 0);
-
- if (value > std::numeric_limits<size_t>::max()) {
- return isolate->Throw(
- *isolate->factory()->NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
- }
-
- allocated_length = static_cast<size_t>(value);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
+ size_t allocated_length = 0;
+ if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
-
if (!Runtime::SetupArrayBufferAllocatingData(isolate,
holder, allocated_length)) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_array_buffer_length",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_array_buffer_length",
+ HandleVector<Object>(NULL, 0)));
}
-
return *holder;
}
@@ -897,15 +897,16 @@
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
- CONVERT_DOUBLE_ARG_CHECKED(first, 2);
- size_t start = static_cast<size_t>(first);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
+ size_t start = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
size_t target_length = NumberToSize(isolate, target->byte_length());
if (target_length == 0) return isolate->heap()->undefined_value();
size_t source_byte_length = NumberToSize(isolate, source->byte_length());
- CHECK(start <= source_byte_length);
- CHECK(source_byte_length - start >= target_length);
+ RUNTIME_ASSERT(start <= source_byte_length);
+ RUNTIME_ASSERT(source_byte_length - start >= target_length);
uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
CopyBytes(target_data, source_data + start, target_length);
@@ -917,14 +918,13 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(Object, object, 0);
- return object->IsJSArrayBufferView()
- ? isolate->heap()->true_value()
- : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) {
HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
if (array_buffer->backing_store() == NULL) {
CHECK(Smi::FromInt(0) == array_buffer->byte_length());
@@ -970,8 +970,8 @@
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
CONVERT_SMI_ARG_CHECKED(arrayId, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
- CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
ASSERT(holder->GetInternalFieldCount() ==
v8::ArrayBufferView::kInternalFieldCount);
@@ -990,19 +990,21 @@
&fixed_elements_kind,
&element_size);
+ size_t byte_offset = 0;
+ size_t byte_length = 0;
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
+
holder->set_byte_offset(*byte_offset_object);
holder->set_byte_length(*byte_length_object);
- size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
- size_t byte_length = NumberToSize(isolate, *byte_length_object);
-
CHECK_EQ(0, static_cast<int>(byte_length % element_size));
size_t length = byte_length / element_size;
if (length > static_cast<unsigned>(Smi::kMaxValue)) {
- return isolate->Throw(*isolate->factory()->
- NewRangeError("invalid_typed_array_length",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(
+ *isolate->factory()->NewRangeError("invalid_typed_array_length",
+ HandleVector<Object>(NULL, 0)));
}
Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
@@ -1137,13 +1139,11 @@
buffer->backing_store(),
backing_store + source_byte_offset,
byte_length);
- return *isolate->factory()->true_value();
- } else {
- return *isolate->factory()->false_value();
+ return isolate->heap()->true_value();
}
}
- return *isolate->factory()->false_value();
+ return isolate->heap()->false_value();
}
@@ -1187,6 +1187,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
@@ -1244,6 +1245,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayMaxSizeInHeap) {
+ ASSERT(args.length() == 0);
ASSERT_OBJECT_SIZE(
FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
@@ -1522,7 +1524,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
table = OrderedHashSet::Add(table, key);
holder->set_table(*table);
@@ -1534,7 +1536,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
return isolate->heap()->ToBoolean(table->Contains(*key));
}
@@ -1544,7 +1546,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
- Handle<Object> key(args[1], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
table = OrderedHashSet::Remove(table, key);
holder->set_table(*table);
@@ -1691,7 +1693,7 @@
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<Object> value(args[2], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
@@ -1703,7 +1705,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (!obj->IsJSObject()) return isolate->heap()->null_value();
return JSObject::cast(obj)->class_name();
}
@@ -1722,7 +1724,7 @@
v8::ACCESS_GET)) {
isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
v8::ACCESS_GET);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
obj = Object::GetPrototype(isolate, obj);
@@ -1752,7 +1754,7 @@
!isolate->MayNamedAccess(
obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
if (obj->map()->is_observed()) {
@@ -1779,8 +1781,8 @@
HandleScope shs(isolate);
ASSERT(args.length() == 2);
// See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
- Handle<Object> O = args.at<Object>(0);
- Handle<Object> V = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
while (true) {
Handle<Object> prototype = Object::GetPrototype(isolate, V);
if (prototype->IsNull()) return isolate->heap()->false_value();
@@ -1995,8 +1997,9 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- Handle<Object> result = JSObject::PreventExtensions(obj);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::PreventExtensions(obj));
return *result;
}
@@ -2021,8 +2024,9 @@
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
- Handle<Object> result = RegExpImpl::Compile(re, pattern, flags);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, RegExpImpl::Compile(re, pattern, flags));
return *result;
}
@@ -2038,7 +2042,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsTemplate) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* arg = args[0];
+ CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
return isolate->heap()->ToBoolean(result);
}
@@ -2048,7 +2052,7 @@
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(HeapObject, templ, 0);
- CONVERT_SMI_ARG_CHECKED(index, 1)
+ CONVERT_SMI_ARG_CHECKED(index, 1);
int offset = index * kPointerSize + HeapObject::kHeaderSize;
InstanceType type = templ->map()->instance_type();
RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
@@ -2148,7 +2152,7 @@
Handle<GlobalObject> global = Handle<GlobalObject>(
isolate->context()->global_object());
- Handle<Context> context = args.at<Context>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
CONVERT_SMI_ARG_CHECKED(flags, 2);
@@ -2220,7 +2224,7 @@
attr = lookup.GetAttributes();
}
// Define or redefine own property.
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
global, name, value, static_cast<PropertyAttributes>(attr)));
} else {
@@ -2245,13 +2249,13 @@
// Declarations are always made in a function or native context. In the
// case of eval code, the context passed is the context of the caller,
// which may be some nested context and not the declaration context.
- RUNTIME_ASSERT(args[0]->IsContext());
- Handle<Context> context(Context::cast(args[0])->declaration_context());
-
- Handle<String> name(String::cast(args[1]));
- PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
+ CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
+ Handle<Context> context(context_arg->declaration_context());
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+ CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
+ PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
- Handle<Object> initial_value(args[3], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
int index;
PropertyAttributes attributes;
@@ -2326,7 +2330,7 @@
}
if (object->IsJSGlobalObject()) {
// Define own property on the global object.
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
} else {
RETURN_FAILURE_ON_EXCEPTION(isolate,
@@ -2350,7 +2354,6 @@
bool assign = args.length() == 3;
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- RUNTIME_ASSERT(args[1]->IsSmi());
CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
// According to ECMA-262, section 12.2, page 62, the property must
@@ -2406,7 +2409,7 @@
// is the second.
RUNTIME_ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
- Handle<Object> value = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
// Get the current global object from top.
GlobalObject* global = isolate->context()->global_object();
@@ -2426,7 +2429,7 @@
if (!lookup.IsFound()) {
HandleScope handle_scope(isolate);
Handle<GlobalObject> global(isolate->context()->global_object());
- RETURN_IF_EMPTY_HANDLE(
+ RETURN_FAILURE_ON_EXCEPTION(
isolate,
JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
attributes));
@@ -2480,14 +2483,12 @@
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- Handle<Object> value(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
ASSERT(!value->IsTheHole());
-
// Initializations are always done in a function or native context.
- RUNTIME_ASSERT(args[1]->IsContext());
- Handle<Context> context(Context::cast(args[1])->declaration_context());
-
- Handle<String> name(String::cast(args[2]));
+ CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
+ Handle<Context> context(context_arg->declaration_context());
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
int index;
PropertyAttributes attributes;
@@ -2613,6 +2614,8 @@
ASSERT(args.length() == 3);
CONVERT_SMI_ARG_CHECKED(size, 0);
RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size);
Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
Handle<JSObject> object =
@@ -2621,8 +2624,8 @@
array->set_elements(*elements);
array->set_length(Smi::FromInt(size));
// Write in-object properties after the length of the array.
- array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
- array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
+ array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
+ array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
return *array;
}
@@ -2671,16 +2674,16 @@
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Handle<Object> zero(Smi::FromInt(0), isolate);
Factory* factory = isolate->factory();
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->source_string(), source, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->global_string(), global, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->ignore_case_string(), ignoreCase, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->multiline_string(), multiline, final));
- CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
- regexp, factory->last_index_string(), zero, writable));
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->source_string(), source, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->global_string(), global, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->ignore_case_string(), ignoreCase, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->multiline_string(), multiline, final).Check();
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ regexp, factory->last_index_string(), zero, writable).Check();
return *regexp;
}
@@ -2783,9 +2786,9 @@
HandleScope scope(isolate);
ASSERT(args.length() == 4);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
- int index = args.smi_at(1);
- Handle<String> pattern = args.at<String>(2);
- Handle<String> flags = args.at<String>(3);
+ CONVERT_SMI_ARG_CHECKED(index, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
+ CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
// Get the RegExp function from the context in the literals array.
// This is the RegExp function from the context in which the
@@ -3008,7 +3011,7 @@
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
- Handle<Object> code = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, code, 1);
if (code->IsNull()) return *target;
RUNTIME_ASSERT(code->IsJSFunction());
@@ -3263,7 +3266,8 @@
HandleScope handlescope(isolate);
ASSERT(args.length() == 1);
if (args[0]->IsNumber()) {
- uint32_t code = NumberToUint32(args[0]) & 0xffff;
+ CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
+ code &= 0xffff;
return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
}
return isolate->heap()->empty_string();
@@ -4361,8 +4365,8 @@
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
- Object* index = args[2];
uint32_t start_index;
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
@@ -4413,8 +4417,8 @@
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
- Object* index = args[2];
uint32_t start_index;
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
@@ -4540,7 +4544,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
HandleScope handles(isolate);
- ASSERT_EQ(3, args.length());
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
@@ -4797,8 +4801,7 @@
return isolate->heap()->infinity_string();
}
char* str = DoubleToRadixCString(value, radix);
- Handle<String> result =
- isolate->factory()->NewStringFromOneByte(OneByteVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
return *result;
}
@@ -4813,8 +4816,7 @@
int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 0);
char* str = DoubleToFixedCString(value, f);
- Handle<String> result =
- isolate->factory()->NewStringFromOneByte(OneByteVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
return *result;
}
@@ -4829,8 +4831,7 @@
int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= -1 && f <= 20);
char* str = DoubleToExponentialCString(value, f);
- Handle<String> result =
- isolate->factory()->NewStringFromOneByte(OneByteVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
return *result;
}
@@ -4845,8 +4846,7 @@
int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 1 && f <= 21);
char* str = DoubleToPrecisionCString(value, f);
- Handle<String> result =
- isolate->factory()->NewStringFromOneByte(OneByteVector(str));
+ Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
DeleteArray(str);
return *result;
}
@@ -4857,11 +4857,7 @@
ASSERT(args.length() == 1);
CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
- if (Smi::IsValid(number)) {
- return isolate->heap()->true_value();
- } else {
- return isolate->heap()->false_value();
- }
+ return isolate->heap()->ToBoolean(Smi::IsValid(number));
}
@@ -4968,8 +4964,8 @@
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- Handle<Object> object = args.at<Object>(0);
- Handle<Object> key = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
@@ -5070,8 +5066,7 @@
Handle<String> str = args.at<String>(0);
int index = args.smi_at(1);
if (index >= 0 && index < str->length()) {
- Handle<Object> result = GetCharAt(str, index);
- return *result;
+ return *GetCharAt(str, index);
}
}
@@ -5113,7 +5108,7 @@
bool fast = obj->HasFastProperties();
JSObject::DefineAccessor(obj, name, getter, setter, attr);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (fast) JSObject::TransformToFastProperties(obj, 0);
return isolate->heap()->undefined_value();
}
@@ -5221,8 +5216,7 @@
Handle<Object> error =
isolate->factory()->NewTypeError("non_object_property_store",
HandleVector(args, 2));
- isolate->Throw(*error);
- return Handle<Object>();
+ return isolate->Throw<Object>(error);
}
if (object->IsJSProxy()) {
@@ -5463,8 +5457,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
SealHandleScope shs(isolate);
RUNTIME_ASSERT(args.length() == 1);
-
- Handle<Object> object = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
if (object->IsJSFunction()) {
JSFunction* func = JSFunction::cast(*object);
@@ -5479,7 +5472,7 @@
RUNTIME_ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_SMI_ARG_CHECKED(store_index, 1);
- Handle<Object> value = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
CONVERT_SMI_ARG_CHECKED(literal_index, 4);
@@ -5536,15 +5529,14 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugCallbackSupportsStepping) {
SealHandleScope shs(isolate);
#ifdef ENABLE_DEBUGGER_SUPPORT
+ ASSERT(args.length() == 1);
if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
return isolate->heap()->false_value();
}
CONVERT_ARG_CHECKED(Object, callback, 0);
// We do not step into the callback if it's a builtin or not even a function.
- if (!callback->IsJSFunction() || JSFunction::cast(callback)->IsBuiltin()) {
- return isolate->heap()->false_value();
- }
- return isolate->heap()->true_value();
+ return isolate->heap()->ToBoolean(
+ callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
#else
return isolate->heap()->false_value();
#endif // ENABLE_DEBUGGER_SUPPORT
@@ -5556,6 +5548,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrepareStepInIfStepping) {
SealHandleScope shs(isolate);
#ifdef ENABLE_DEBUGGER_SUPPORT
+ ASSERT(args.length() == 1);
Debug* debug = isolate->debug();
if (!debug->IsStepping()) return isolate->heap()->undefined_value();
CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
@@ -5628,7 +5621,7 @@
Handle<JSObject>::cast(proto),
key);
}
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->false_value();
}
@@ -5636,8 +5629,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
- Handle<Object> object = args.at<Object>(0);
uint32_t index;
const bool key_is_array_index = key->AsArrayIndex(&index);
@@ -5652,7 +5645,7 @@
ASSERT(!isolate->has_scheduled_exception());
return isolate->heap()->true_value();
} else {
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
}
Map* map = js_obj->map();
if (!key_is_array_index &&
@@ -5682,7 +5675,7 @@
CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
bool result = JSReceiver::HasProperty(receiver, key);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (isolate->has_pending_exception()) return Failure::Exception();
return isolate->heap()->ToBoolean(result);
}
@@ -5695,8 +5688,7 @@
CONVERT_SMI_ARG_CHECKED(index, 1);
bool result = JSReceiver::HasElement(receiver, index);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
- if (isolate->has_pending_exception()) return Failure::Exception();
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->ToBoolean(result);
}
@@ -5710,7 +5702,7 @@
PropertyAttributes att = JSReceiver::GetLocalPropertyAttribute(object, key);
if (att == ABSENT || (att & DONT_ENUM) != 0) {
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->false_value();
}
ASSERT(!isolate->has_scheduled_exception());
@@ -5796,7 +5788,7 @@
!isolate->MayNamedAccess(
obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
@@ -5815,7 +5807,7 @@
!isolate->MayNamedAccess(
jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
int n;
@@ -5961,7 +5953,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_LocalKeys) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 1);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
Handle<JSObject> object(raw_object);
@@ -5971,7 +5963,7 @@
!isolate->MayNamedAccess(
object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
@@ -6011,6 +6003,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArgumentsProperty) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
// Compute the frame holding the arguments.
JavaScriptFrameIterator it(isolate);
@@ -6023,25 +6016,25 @@
// Try to convert the key to an index. If successful and within
// index return the the argument from the frame.
uint32_t index;
- if (args[0]->ToArrayIndex(&index) && index < n) {
+ if (raw_key->ToArrayIndex(&index) && index < n) {
return frame->GetParameter(index);
}
HandleScope scope(isolate);
- if (args[0]->IsSymbol()) {
+ if (raw_key->IsSymbol()) {
// Lookup in the initial Object.prototype object.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Object::GetProperty(
- isolate->initial_object_prototype(), args.at<Symbol>(0)));
+ Object::GetProperty(isolate->initial_object_prototype(),
+ Handle<Symbol>::cast(raw_key)));
return *result;
}
// Convert the key to a string.
Handle<Object> converted;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, converted, Execution::ToString(isolate, args.at<Object>(0)));
+ isolate, converted, Execution::ToString(isolate, raw_key));
Handle<String> key = Handle<String>::cast(converted);
// Try to convert the string key into an array index.
@@ -6094,8 +6087,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, object, 0);
- return isolate->heap()->ToBoolean(args[0]->BooleanValue());
+ return isolate->heap()->ToBoolean(object->BooleanValue());
}
@@ -6103,8 +6097,8 @@
// Possible optimizations: put the type string into the oddballs.
RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
SealHandleScope shs(isolate);
-
- Object* obj = args[0];
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsNumber()) return isolate->heap()->number_string();
HeapObject* heap_obj = HeapObject::cast(obj);
@@ -6229,20 +6223,26 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewString) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(length, 0);
CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
if (length == 0) return isolate->heap()->empty_string();
+ Handle<String> result;
if (is_one_byte) {
- return isolate->heap()->AllocateRawOneByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawOneByteString(length));
} else {
- return isolate->heap()->AllocateRawTwoByteString(length);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, isolate->factory()->NewRawTwoByteString(length));
}
+ return *result;
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_TruncateString) {
HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
CONVERT_SMI_ARG_CHECKED(new_length, 1);
return *SeqString::Truncate(string, new_length);
@@ -6295,16 +6295,18 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
BasicJsonStringifier stringifier(isolate);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, stringifier.Stringify(args.at<Object>(0)));
+ isolate, result, stringifier.Stringify(object));
return *result;
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
HandleScope handle_scope(isolate);
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
@@ -6331,6 +6333,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseFloat) {
HandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
subject = String::Flatten(subject);
@@ -6575,11 +6578,9 @@
template <class Converter>
MUST_USE_RESULT static MaybeObject* ConvertCase(
- Arguments args,
+ Handle<String> s,
Isolate* isolate,
unibrow::Mapping<Converter, 128>* mapping) {
- HandleScope handle_scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
s = String::Flatten(s);
int length = s->length();
// Assume that the string is not empty; we need this assumption later
@@ -6605,7 +6606,7 @@
length,
&has_changed_character);
// If not ASCII, we discard the result and take the 2 byte path.
- if (is_ascii) return has_changed_character ? *result : *s;
+ if (is_ascii) return has_changed_character ? *result : *s;
}
Handle<SeqString> result; // Same length as input.
@@ -6635,14 +6636,20 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToLowerCase) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
- args, isolate, isolate->runtime_state()->to_lower_mapping());
+ s, isolate, isolate->runtime_state()->to_lower_mapping());
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToUpperCase) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
return ConvertCase(
- args, isolate, isolate->runtime_state()->to_upper_mapping());
+ s, isolate, isolate->runtime_state()->to_upper_mapping());
}
@@ -6871,9 +6878,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToString) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> number = args.at<Object>(0);
- RUNTIME_ASSERT(number->IsNumber());
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
return *isolate->factory()->NumberToString(number);
}
@@ -6882,9 +6887,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToStringSkipCache) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> number = args.at<Object>(0);
- RUNTIME_ASSERT(number->IsNumber());
+ CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
return *isolate->factory()->NumberToString(number, false);
}
@@ -6935,8 +6938,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NumberToSmi) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
-
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
if (obj->IsSmi()) {
return obj;
}
@@ -7045,6 +7047,7 @@
sinkchar* sink,
FixedArray* fixed_array,
int array_length) {
+ DisallowHeapAllocation no_gc;
int position = 0;
for (int i = 0; i < array_length; i++) {
Object* element = fixed_array->get(i);
@@ -7079,36 +7082,13 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
- if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- int array_length = args.smi_at(1);
- CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
-
- // This assumption is used by the slice encoding in one or two smis.
- ASSERT(Smi::kMaxValue >= String::kMaxLength);
-
- JSObject::EnsureCanContainHeapObjectElements(array);
-
- int special_length = special->length();
- if (!array->HasFastObjectElements()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
- FixedArray* fixed_array = FixedArray::cast(array->elements());
- if (fixed_array->length() < array_length) {
- array_length = fixed_array->length();
- }
-
- if (array_length == 0) {
- return isolate->heap()->empty_string();
- } else if (array_length == 1) {
- Object* first = fixed_array->get(0);
- if (first->IsString()) return first;
- }
-
- bool one_byte = special->HasOnlyOneByteChars();
+// Returns the result length of the concatenation.
+// On illegal argument, -1 is returned.
+static inline int StringBuilderConcatLength(int special_length,
+ FixedArray* fixed_array,
+ int array_length,
+ bool* one_byte) {
+ DisallowHeapAllocation no_gc;
int position = 0;
for (int i = 0; i < array_length; i++) {
int increment = 0;
@@ -7127,66 +7107,97 @@
len = -smi_value;
// Get the position and check that it is a positive smi.
i++;
- if (i >= array_length) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (i >= array_length) return -1;
Object* next_smi = fixed_array->get(i);
- if (!next_smi->IsSmi()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (!next_smi->IsSmi()) return -1;
pos = Smi::cast(next_smi)->value();
- if (pos < 0) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (pos < 0) return -1;
}
ASSERT(pos >= 0);
ASSERT(len >= 0);
- if (pos > special_length || len > special_length - pos) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
+ if (pos > special_length || len > special_length - pos) return -1;
increment = len;
} else if (elt->IsString()) {
String* element = String::cast(elt);
int element_length = element->length();
increment = element_length;
- if (one_byte && !element->HasOnlyOneByteChars()) {
- one_byte = false;
+ if (*one_byte && !element->HasOnlyOneByteChars()) {
+ *one_byte = false;
}
} else {
ASSERT(!elt->IsTheHole());
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return -1;
}
if (increment > String::kMaxLength - position) {
- return isolate->ThrowInvalidStringLength();
+ return kMaxInt; // Provoke throw on allocation.
}
position += increment;
}
+ return position;
+}
- int length = position;
- Object* object;
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+ if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
+ CONVERT_SMI_ARG_CHECKED(array_length, 1);
+ CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
+
+ // This assumption is used by the slice encoding in one or two smis.
+ ASSERT(Smi::kMaxValue >= String::kMaxLength);
+
+ JSObject::EnsureCanContainHeapObjectElements(array);
+
+ int special_length = special->length();
+ if (!array->HasFastObjectElements()) {
+ return isolate->Throw(isolate->heap()->illegal_argument_string());
+ }
+
+ int length;
+ bool one_byte = special->HasOnlyOneByteChars();
+
+ { DisallowHeapAllocation no_gc;
+ FixedArray* fixed_array = FixedArray::cast(array->elements());
+ if (fixed_array->length() < array_length) {
+ array_length = fixed_array->length();
+ }
+
+ if (array_length == 0) {
+ return isolate->heap()->empty_string();
+ } else if (array_length == 1) {
+ Object* first = fixed_array->get(0);
+ if (first->IsString()) return first;
+ }
+ length = StringBuilderConcatLength(
+ special_length, fixed_array, array_length, &one_byte);
+ }
+
+ if (length == -1) {
+ return isolate->Throw(isolate->heap()->illegal_argument_string());
+ }
if (one_byte) {
- { MaybeObject* maybe_object =
- isolate->heap()->AllocateRawOneByteString(length);
- if (!maybe_object->ToObject(&object)) return maybe_object;
- }
- SeqOneByteString* answer = SeqOneByteString::cast(object);
+ Handle<SeqOneByteString> answer;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, answer,
+ isolate->factory()->NewRawOneByteString(length));
StringBuilderConcatHelper(*special,
answer->GetChars(),
- fixed_array,
+ FixedArray::cast(array->elements()),
array_length);
- return answer;
+ return *answer;
} else {
- { MaybeObject* maybe_object =
- isolate->heap()->AllocateRawTwoByteString(length);
- if (!maybe_object->ToObject(&object)) return maybe_object;
- }
- SeqTwoByteString* answer = SeqTwoByteString::cast(object);
+ Handle<SeqTwoByteString> answer;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, answer,
+ isolate->factory()->NewRawTwoByteString(length));
StringBuilderConcatHelper(*special,
answer->GetChars(),
- fixed_array,
+ FixedArray::cast(array->elements()),
array_length);
- return answer;
+ return *answer;
}
}
@@ -7196,7 +7207,7 @@
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
- int array_length = args.smi_at(1);
+ CONVERT_SMI_ARG_CHECKED(array_length, 1);
CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
RUNTIME_ASSERT(array->HasFastObjectElements());
@@ -7900,9 +7911,9 @@
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- Handle<JSFunction> callee = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
Object** parameters = reinterpret_cast<Object**>(args[1]);
- const int argument_count = Smi::cast(args[2])->value();
+ CONVERT_SMI_ARG_CHECKED(argument_count, 2);
Handle<JSObject> result =
isolate->factory()->NewArgumentsObject(callee, argument_count);
@@ -8020,11 +8031,8 @@
CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
Handle<Context> context(isolate->context());
PretenureFlag pretenure_flag = NOT_TENURED;
- Handle<JSFunction> result =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
- context,
- pretenure_flag);
- return *result;
+ return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, context, pretenure_flag);
}
@@ -8038,11 +8046,8 @@
// The caller ensures that we pretenure closures that are assigned
// directly to properties.
PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
- Handle<JSFunction> result =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
- context,
- pretenure_flag);
- return *result;
+ return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, context, pretenure_flag);
}
@@ -8281,7 +8286,6 @@
} else {
result = isolate->factory()->NewJSObjectWithMemento(function, site);
}
- RETURN_IF_EMPTY_HANDLE(isolate, result);
isolate->counters()->constructed_objects()->Increment();
isolate->counters()->constructed_objects_runtime()->Increment();
@@ -8293,8 +8297,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewObject) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> constructor = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
return Runtime_NewObjectHelper(isolate,
constructor,
Handle<AllocationSite>::null());
@@ -8304,17 +8307,14 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NewObjectWithAllocationSite) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
-
- Handle<Object> constructor = args.at<Object>(1);
- Handle<Object> feedback = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
Handle<AllocationSite> site;
if (feedback->IsAllocationSite()) {
// The feedback can be an AllocationSite or undefined.
site = Handle<AllocationSite>::cast(feedback);
}
- return Runtime_NewObjectHelper(isolate,
- constructor,
- site);
+ return Runtime_NewObjectHelper(isolate, constructor, site);
}
@@ -8332,8 +8332,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileUnoptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<JSFunction> function = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
#ifdef DEBUG
if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
PrintF("[unoptimized: ");
@@ -8361,7 +8360,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_CompileOptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- Handle<JSFunction> function = args.at<JSFunction>(0);
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
Handle<Code> unoptimized(function->shared()->code());
@@ -8434,9 +8433,9 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_NotifyDeoptimized) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(args[0]->IsSmi());
+ CONVERT_SMI_ARG_CHECKED(type_arg, 0);
Deoptimizer::BailoutType type =
- static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
+ static_cast<Deoptimizer::BailoutType>(type_arg);
Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
ASSERT(AllowHeapAllocation::IsAllowed());
@@ -8517,6 +8516,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
#if defined(USE_SIMULATOR)
return isolate->heap()->true_value();
#else
@@ -8526,9 +8526,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsConcurrentRecompilationSupported) {
- HandleScope scope(isolate);
- return isolate->concurrent_recompilation_enabled()
- ? isolate->heap()->true_value() : isolate->heap()->false_value();
+ SealHandleScope shs(isolate);
+ return isolate->heap()->ToBoolean(
+ isolate->concurrent_recompilation_enabled());
}
@@ -8612,6 +8612,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_UnblockConcurrentRecompilation) {
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
isolate->optimizing_compiler_thread()->Unblock();
@@ -8783,6 +8784,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckIsBootstrapping) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->undefined_value();
}
@@ -8790,6 +8792,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetRootNaN) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
return isolate->heap()->nan_value();
}
@@ -8814,10 +8817,7 @@
}
for (int i = 0; i < argc; ++i) {
- MaybeObject* maybe = args[1 + i];
- Object* object;
- if (!maybe->To<Object>(&object)) return maybe;
- argv[i] = Handle<Object>(object, isolate);
+ argv[i] = Handle<Object>(args[1 + i], isolate);
}
Handle<JSReceiver> hfun(fun);
@@ -8834,7 +8834,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
- Handle<Object> receiver = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
CONVERT_SMI_ARG_CHECKED(offset, 3);
CONVERT_SMI_ARG_CHECKED(argc, 4);
@@ -8869,16 +8869,18 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetFunctionDelegate(isolate, args.at<Object>(0));
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ RUNTIME_ASSERT(!object->IsJSFunction());
+ return *Execution::GetFunctionDelegate(isolate, object);
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(!args[0]->IsJSFunction());
- return *Execution::GetConstructorDelegate(isolate, args.at<Object>(0));
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ RUNTIME_ASSERT(!object->IsJSFunction());
+ return *Execution::GetConstructorDelegate(isolate, object);
}
@@ -8904,9 +8906,7 @@
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
int length = function->shared()->scope_info()->ContextLength();
- Handle<Context> context =
- isolate->factory()->NewFunctionContext(length, function);
- return *context;
+ return *isolate->factory()->NewFunctionContext(length, function);
}
@@ -8993,7 +8993,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSModule) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* obj = args[0];
+ CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSModule());
}
@@ -9058,8 +9058,9 @@
IsImmutableVariableMode(mode) ? FROZEN : SEALED;
Handle<AccessorInfo> info =
Accessors::MakeModuleExport(name, index, attr);
- Handle<Object> result = JSObject::SetAccessor(module, info);
- ASSERT(!(result.is_null() || result->IsUndefined()));
+ Handle<Object> result =
+ JSObject::SetAccessor(module, info).ToHandleChecked();
+ ASSERT(!result->IsUndefined());
USE(result);
break;
}
@@ -9078,7 +9079,7 @@
}
}
- JSObject::PreventExtensions(module);
+ JSObject::PreventExtensions(module).Assert();
}
ASSERT(!isolate->has_pending_exception());
@@ -9294,7 +9295,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- Handle<Object> value(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
@@ -9393,7 +9394,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_PromoteScheduledException) {
SealHandleScope shs(isolate);
- ASSERT_EQ(0, args.length());
+ ASSERT(args.length() == 0);
return isolate->PromoteScheduledException();
}
@@ -9401,8 +9402,7 @@
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_ThrowReferenceError) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- Handle<Object> name(args[0], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
Handle<Object> reference_error =
isolate->factory()->NewReferenceError("not_defined",
HandleVector(&name, 1));
@@ -9425,8 +9425,7 @@
const char* message = GetBailoutReason(
static_cast<BailoutReason>(message_id));
Handle<String> message_handle =
- isolate->factory()->NewStringFromAscii(CStrVector(message));
- RETURN_IF_EMPTY_HANDLE(isolate, message_handle);
+ isolate->factory()->NewStringFromAsciiChecked(message);
return isolate->Throw(*message_handle);
}
@@ -9507,8 +9506,10 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) {
SealHandleScope shs(isolate);
- PrintTransition(isolate, args[0]);
- return args[0]; // return TOS
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ PrintTransition(isolate, obj);
+ return obj; // return TOS
}
@@ -9606,7 +9607,9 @@
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
const char* zone =
isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
- return *isolate->factory()->NewStringFromUtf8(CStrVector(zone));
+ Handle<String> result = isolate->factory()->NewStringFromUtf8(
+ CStrVector(zone)).ToHandleChecked();
+ return *result;
}
@@ -9645,7 +9648,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalReceiver) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* global = args[0];
+ CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
return JSGlobalObject::cast(global)->global_receiver();
}
@@ -9654,7 +9657,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAttachedGlobal) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
- Object* global = args[0];
+ CONVERT_ARG_CHECKED(Object, global, 0);
if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
return isolate->heap()->ToBoolean(
!JSGlobalObject::cast(global)->IsDetached());
@@ -9663,7 +9666,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
HandleScope scope(isolate);
- ASSERT_EQ(1, args.length());
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
source = String::Flatten(source);
@@ -9696,7 +9699,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
HandleScope scope(isolate);
- ASSERT_EQ(2, args.length());
+ ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
@@ -9716,9 +9719,11 @@
// Compile source string in the native context.
ParseRestriction restriction = function_literal_only
? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
- Handle<JSFunction> fun = Compiler::GetFunctionFromEval(
- source, context, SLOPPY, restriction, RelocInfo::kNoPosition);
- RETURN_IF_EMPTY_HANDLE(isolate, fun);
+ Handle<JSFunction> fun;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, fun,
+ Compiler::GetFunctionFromEval(
+ source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
return *fun;
}
@@ -9745,10 +9750,12 @@
// Deal with a normal eval call with a string argument. Compile it
// and return the compiled function bound in the local context.
static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
- Handle<JSFunction> compiled = Compiler::GetFunctionFromEval(
- source, context, strict_mode, restriction, scope_position);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate, compiled,
- MakePair(Failure::Exception(), NULL));
+ Handle<JSFunction> compiled;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, compiled,
+ Compiler::GetFunctionFromEval(
+ source, context, strict_mode, restriction, scope_position),
+ MakePair(Failure::Exception(), NULL));
return MakePair(*compiled, *receiver);
}
@@ -9781,45 +9788,28 @@
}
-// Allocate a block of memory in the given space (filled with a filler).
-// Used as a fall-back for generated code when the space is full.
-static MaybeObject* Allocate(Isolate* isolate,
- int size,
- bool double_align,
- AllocationSpace space) {
- Heap* heap = isolate->heap();
+RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateInNewSpace) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_SMI_ARG_CHECKED(size, 0);
RUNTIME_ASSERT(IsAligned(size, kPointerSize));
RUNTIME_ASSERT(size > 0);
RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
- HeapObject* allocation;
- { MaybeObject* maybe_allocation = heap->AllocateRaw(size, space, space);
- if (!maybe_allocation->To(&allocation)) return maybe_allocation;
- }
-#ifdef DEBUG
- MemoryChunk* chunk = MemoryChunk::FromAddress(allocation->address());
- ASSERT(chunk->owner()->identity() == space);
-#endif
- heap->CreateFillerObjectAt(allocation->address(), size);
- return allocation;
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateInNewSpace) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- CONVERT_SMI_ARG_CHECKED(size, 0);
- return Allocate(isolate, size, false, NEW_SPACE);
+ return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
}
RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_AllocateInTargetSpace) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_SMI_ARG_CHECKED(size, 0);
CONVERT_SMI_ARG_CHECKED(flags, 1);
+ RUNTIME_ASSERT(IsAligned(size, kPointerSize));
+ RUNTIME_ASSERT(size > 0);
+ RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
bool double_align = AllocateDoubleAlignFlag::decode(flags);
AllocationSpace space = AllocateTargetSpace::decode(flags);
- return Allocate(isolate, size, double_align, space);
+ return *isolate->factory()->NewFillerObject(size, double_align, space);
}
@@ -10631,9 +10621,10 @@
CONVERT_SMI_ARG_CHECKED(flag, 2);
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
- Handle<Object> result =
- JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
return *result;
}
@@ -10668,8 +10659,8 @@
RUNTIME_ASSERT(args[0]->IsJSFunction() ||
args[0]->IsUndefined() ||
args[0]->IsNull());
- Handle<Object> callback = args.at<Object>(0);
- Handle<Object> data = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
isolate->debugger()->SetEventListener(callback, data);
return isolate->heap()->undefined_value();
@@ -10912,17 +10903,17 @@
}
+static bool CheckExecutionState(Isolate* isolate, int break_id) {
+ return (isolate->debug()->break_id() != 0 &&
+ break_id == isolate->debug()->break_id());
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_CheckExecutionState) {
SealHandleScope shs(isolate);
- ASSERT(args.length() >= 1);
+ ASSERT(args.length() == 1);
CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- // Check that the break id is valid.
- if (isolate->debug()->break_id() == 0 ||
- break_id != isolate->debug()->break_id()) {
- return isolate->Throw(
- isolate->heap()->illegal_execution_state_string());
- }
-
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
return isolate->heap()->true_value();
}
@@ -10930,13 +10921,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- // Check arguments.
- Object* result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Count all frames which are relevant to debugging stack trace.
int n = 0;
@@ -11073,13 +11059,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
Heap* heap = isolate->heap();
@@ -12103,13 +12085,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
// Get the frame where the debugging is performed.
@@ -12135,13 +12113,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
// Get the frame where the debugging is performed.
@@ -12246,13 +12220,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
@@ -12290,13 +12260,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAllScopesDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 3 || args.length() == 4);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
@@ -12366,7 +12332,6 @@
Handle<JSObject> details;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, details, MaterializeScopeDetails(isolate, &it));
- RETURN_IF_EMPTY_HANDLE(isolate, details);
return *details;
}
@@ -12400,15 +12365,13 @@
// Check arguments.
CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
- Handle<Object> new_value = args.at<Object>(5);
+ CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
bool res;
if (args[0]->IsNumber()) {
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
@@ -12450,13 +12413,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadCount) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
-
- // Check arguments.
- Object* result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
// Count all archived V8 threads.
int n = 0;
@@ -12486,13 +12444,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetThreadDetails) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
// Allocate array for result.
@@ -12581,7 +12535,7 @@
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
- Handle<Object> break_point_object_arg = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
// Set break point.
isolate->debug()->SetBreakPoint(function, break_point_object_arg,
@@ -12605,7 +12559,7 @@
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
- Handle<Object> break_point_object_arg = args.at<Object>(3);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
return isolate->ThrowIllegalOperation();
@@ -12633,7 +12587,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearBreakPoint) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- Handle<Object> break_point_object_arg = args.at<Object>(0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
// Clear break point.
isolate->debug()->ClearBreakPoint(break_point_object_arg);
@@ -12648,13 +12602,12 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_ChangeBreakOnException) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
- RUNTIME_ASSERT(args[0]->IsNumber());
+ CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
// If the number doesn't match an enum value, the ChangeBreakOnException
// function will default to affecting caught exceptions.
- ExceptionBreakType type =
- static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
+ ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
// Update break point state.
isolate->debug()->ChangeBreakOnException(type, enable);
return isolate->heap()->undefined_value();
@@ -12666,10 +12619,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsBreakOnException) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- RUNTIME_ASSERT(args[0]->IsNumber());
+ CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
- ExceptionBreakType type =
- static_cast<ExceptionBreakType>(NumberToUint32(args[0]));
+ ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
bool result = isolate->debug()->IsBreakOnException(type);
return Smi::FromInt(result);
}
@@ -12683,12 +12635,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
HandleScope scope(isolate);
ASSERT(args.length() == 4);
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
return isolate->Throw(isolate->heap()->illegal_argument_string());
}
@@ -12771,29 +12720,32 @@
// Compile and evaluate source for the given context.
-static MaybeObject* DebugEvaluate(Isolate* isolate,
- Handle<Context> context,
- Handle<Object> context_extension,
- Handle<Object> receiver,
- Handle<String> source) {
+static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
+ Handle<Context> context,
+ Handle<Object> context_extension,
+ Handle<Object> receiver,
+ Handle<String> source) {
if (context_extension->IsJSObject()) {
Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
Handle<JSFunction> closure(context->closure(), isolate);
context = isolate->factory()->NewWithContext(closure, context, extension);
}
- Handle<JSFunction> eval_fun =
+ Handle<JSFunction> eval_fun;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, eval_fun,
Compiler::GetFunctionFromEval(source,
context,
SLOPPY,
NO_PARSE_RESTRICTION,
- RelocInfo::kNoPosition);
- RETURN_IF_EMPTY_HANDLE(isolate, eval_fun);
+ RelocInfo::kNoPosition),
+ Object);
Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
- Execution::Call(isolate, eval_fun, receiver, 0, NULL));
+ Execution::Call(isolate, eval_fun, receiver, 0, NULL),
+ Object);
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
@@ -12803,7 +12755,7 @@
// Clear the oneshot breakpoints so that the debugger does not step further.
isolate->debug()->ClearStepping();
- return *result;
+ return result;
}
@@ -12818,16 +12770,14 @@
// Check the execution state and decode arguments frame and source to be
// evaluated.
ASSERT(args.length() == 6);
- Object* check_result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&check_result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
- Handle<Object> context_extension(args[5], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
// Handle the processing of break.
DisableBreak disable_break_save(isolate, disable_break);
@@ -12867,13 +12817,10 @@
context = isolate->factory()->NewWithContext(function, context, materialized);
Handle<Object> receiver(frame->receiver(), isolate);
- Object* evaluate_result_object;
- { MaybeObject* maybe_result =
- DebugEvaluate(isolate, context, context_extension, receiver, source);
- if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result;
- }
-
- Handle<Object> result(evaluate_result_object, isolate);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ DebugEvaluate(isolate, context, context_extension, receiver, source));
// Write back potential changes to materialized stack locals to the stack.
UpdateStackLocalsFromMaterializedObject(
@@ -12889,14 +12836,12 @@
// Check the execution state and decode arguments frame and source to be
// evaluated.
ASSERT(args.length() == 4);
- Object* check_result;
- { MaybeObject* maybe_result = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_result->ToObject(&check_result)) return maybe_result;
- }
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
+
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
- Handle<Object> context_extension(args[3], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
// Handle the processing of break.
DisableBreak disable_break_save(isolate, disable_break);
@@ -12915,7 +12860,11 @@
// debugger was invoked.
Handle<Context> context = isolate->native_context();
Handle<Object> receiver = isolate->global_object();
- return DebugEvaluate(isolate, context, context_extension, receiver, source);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result,
+ DebugEvaluate(isolate, context, context_extension, receiver, source));
+ return *result;
}
@@ -13035,7 +12984,7 @@
// Check parameters.
CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
- Handle<Object> instance_filter = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
RUNTIME_ASSERT(instance_filter->IsUndefined() ||
instance_filter->IsJSObject());
CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
@@ -13335,7 +13284,7 @@
ASSERT(args.length() == 3);
CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
- Handle<Object> old_script_name(args[2], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
RUNTIME_ASSERT(original_script_value->value()->IsScript());
Handle<Script> original_script(Script::cast(original_script_value->value()));
@@ -13383,8 +13332,8 @@
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
- Handle<Object> function_object(args[0], isolate);
- Handle<Object> script_object(args[1], isolate);
+ CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
if (function_object->IsJSValue()) {
Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
@@ -13474,13 +13423,9 @@
HandleScope scope(isolate);
CHECK(isolate->debugger()->live_edit_enabled());
ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+ RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
- // Check arguments.
- Object* check;
- { MaybeObject* maybe_check = Runtime_CheckExecutionState(
- RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check->ToObject(&check)) return maybe_check;
- }
CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
Heap* heap = isolate->heap();
@@ -13577,6 +13522,7 @@
// Sets a v8 flag.
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetFlags) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(String, arg, 0);
SmartArrayPointer<char> flags =
arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
@@ -13589,6 +13535,7 @@
// Presently, it only does a full GC.
RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectGarbage) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
return isolate->heap()->undefined_value();
}
@@ -13597,6 +13544,7 @@
// Gets the current heap usage.
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 0);
int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
if (!Smi::IsValid(usage)) {
return *isolate->factory()->NewNumberFromInt(usage);
@@ -13627,7 +13575,7 @@
uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
&icu_length, &error);
if (U_FAILURE(error) || icu_length == 0) {
- return *factory->NewStringFromOneByte(OneByteVector(kInvalidTag));
+ return *factory->NewStringFromAsciiChecked(kInvalidTag);
}
char result[ULOC_FULLNAME_CAPACITY];
@@ -13636,15 +13584,16 @@
uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
if (U_FAILURE(error)) {
- return *factory->NewStringFromOneByte(OneByteVector(kInvalidTag));
+ return *factory->NewStringFromAsciiChecked(kInvalidTag);
}
- return *factory->NewStringFromOneByte(OneByteVector(result));
+ return *factory->NewStringFromAsciiChecked(result);
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
@@ -13665,7 +13614,7 @@
UErrorCode error = U_ZERO_ERROR;
char result[ULOC_FULLNAME_CAPACITY];
Handle<JSObject> locales =
- isolate->factory()->NewJSObject(isolate->object_function());
+ factory->NewJSObject(isolate->object_function());
for (int32_t i = 0; i < count; ++i) {
const char* icu_name = available_locales[i].getName();
@@ -13678,11 +13627,11 @@
continue;
}
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
locales,
- isolate->factory()->NewStringFromAscii(CStrVector(result)),
- isolate->factory()->NewNumber(i),
+ factory->NewStringFromAsciiChecked(result),
+ factory->NewNumber(i),
NONE));
}
@@ -13704,32 +13653,31 @@
uloc_toLanguageTag(
default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
if (U_SUCCESS(status)) {
- return *factory->NewStringFromOneByte(OneByteVector(result));
+ return *factory->NewStringFromAsciiChecked(result);
}
- return *factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("und"));
+ return *factory->NewStringFromStaticAscii("und");
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
HandleScope scope(isolate);
+ Factory* factory = isolate->factory();
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
uint32_t length = static_cast<uint32_t>(input->length()->Number());
- Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
- Handle<Name> maximized =
- isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
- Handle<Name> base =
- isolate->factory()->NewStringFromAscii(CStrVector("base"));
+ Handle<FixedArray> output = factory->NewFixedArray(length);
+ Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
+ Handle<Name> base = factory->NewStringFromStaticAscii("base");
for (unsigned int i = 0; i < length; ++i) {
Handle<Object> locale_id;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, locale_id, Object::GetElement(isolate, input, i));
if (!locale_id->IsString()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
v8::String::Utf8Value utf8_locale_id(
@@ -13744,7 +13692,7 @@
uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
&icu_locale_length, &error);
if (U_FAILURE(error) || icu_locale_length == 0) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
// Maximize the locale.
@@ -13777,27 +13725,26 @@
icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
if (U_FAILURE(error)) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
+ return isolate->Throw(*factory->illegal_argument_string());
}
- Handle<JSObject> result =
- isolate->factory()->NewJSObject(isolate->object_function());
- RETURN_IF_EMPTY_HANDLE(isolate,
+ Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
result,
maximized,
- isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
+ factory->NewStringFromAsciiChecked(base_max_locale),
NONE));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
result,
base,
- isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
+ factory->NewStringFromAsciiChecked(base_locale),
NONE));
output->set(i, *result);
}
- Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
+ Handle<JSArray> result = factory->NewJSArrayWithElements(output);
result->set_length(Smi::FromInt(length));
return *result;
}
@@ -13810,7 +13757,7 @@
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
- if (!input->IsJSObject()) return isolate->heap()->ToBoolean(false);
+ if (!input->IsJSObject()) return isolate->heap()->false_value();
Handle<JSObject> obj = Handle<JSObject>::cast(input);
Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
@@ -13827,7 +13774,7 @@
CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
- if (!input->IsJSObject()) return isolate->heap()->ToBoolean(false);
+ if (!input->IsJSObject()) return isolate->heap()->false_value();
Handle<JSObject> obj = Handle<JSObject>::cast(input);
Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
@@ -13910,11 +13857,11 @@
local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("dateFormat"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
// Make object handle weak so we can delete the data format once GC kicks in.
@@ -13945,10 +13892,14 @@
icu::UnicodeString result;
date_format->format(value->Number(), result);
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
@@ -14005,11 +13956,11 @@
local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("numberFormat")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("numberFormat"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
@@ -14039,10 +13990,14 @@
icu::UnicodeString result;
number_format->format(value->Number(), result);
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
@@ -14109,11 +14064,11 @@
local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("collator")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("collator"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
@@ -14174,10 +14129,14 @@
return isolate->heap()->undefined_value();
}
- return *isolate->factory()->NewStringFromTwoByte(
- Vector<const uint16_t>(
- reinterpret_cast<const uint16_t*>(result.getBuffer()),
- result.length()));
+ Handle<String> result_str;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result_str,
+ isolate->factory()->NewStringFromTwoByte(
+ Vector<const uint16_t>(
+ reinterpret_cast<const uint16_t*>(result.getBuffer()),
+ result.length())));
+ return *result_str;
}
@@ -14209,11 +14168,11 @@
// Make sure that the pointer to adopted text is NULL.
local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
- RETURN_IF_EMPTY_HANDLE(isolate,
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
JSObject::SetLocalPropertyIgnoreAttributes(
local_object,
- isolate->factory()->NewStringFromAscii(CStrVector("breakIterator")),
- isolate->factory()->NewStringFromAscii(CStrVector("valid")),
+ isolate->factory()->NewStringFromStaticAscii("breakIterator"),
+ isolate->factory()->NewStringFromStaticAscii("valid"),
NONE));
// Make object handle weak so we can delete the break iterator once GC kicks
@@ -14315,17 +14274,17 @@
int32_t status = rule_based_iterator->getRuleStatus();
// Keep return values in sync with JavaScript BreakType enum.
if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("none"));
+ return *isolate->factory()->NewStringFromStaticAscii("none");
} else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("number"));
+ return *isolate->factory()->NewStringFromStaticAscii("number");
} else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("letter"));
+ return *isolate->factory()->NewStringFromStaticAscii("letter");
} else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("kana"));
+ return *isolate->factory()->NewStringFromStaticAscii("kana");
} else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
- return *isolate->factory()->NewStringFromAscii(CStrVector("ideo"));
+ return *isolate->factory()->NewStringFromStaticAscii("ideo");
} else {
- return *isolate->factory()->NewStringFromAscii(CStrVector("unknown"));
+ return *isolate->factory()->NewStringFromStaticAscii("unknown");
}
}
#endif // V8_I18N_SUPPORT
@@ -14389,9 +14348,9 @@
// native code offset.
RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 3);
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
- Handle<Object> caller = args.at<Object>(1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
// Optionally capture a more detailed stack trace for the message.
@@ -14405,7 +14364,7 @@
// be formatted. Since we only need this once, clear it afterwards.
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetAndClearOverflowedStackTrace) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 1);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
Handle<String> key = isolate->factory()->hidden_stack_trace_string();
Handle<Object> result(error_object->GetHiddenProperty(*key), isolate);
@@ -14419,12 +14378,11 @@
// Returns V8 version as a string.
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
HandleScope scope(isolate);
- ASSERT_EQ(args.length(), 0);
+ ASSERT(args.length() == 0);
const char* version_string = v8::V8::GetVersion();
- return *isolate->factory()->NewStringFromOneByte(
- OneByteVector(version_string), NOT_TENURED);
+ return *isolate->factory()->NewStringFromAsciiChecked(version_string);
}
@@ -14504,7 +14462,7 @@
SealHandleScope shs(isolate);
// This is only called from codegen, so checks might be more lax.
CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
- Object* key = args[1];
+ CONVERT_ARG_CHECKED(Object, key, 1);
{
DisallowHeapAllocation no_alloc;
@@ -14600,6 +14558,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetStartPosition) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return Smi::FromInt(message->start_position());
}
@@ -14607,6 +14566,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MessageGetScript) {
SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
return message->script();
}
@@ -14634,11 +14594,9 @@
Handle<String> name; \
/* Inline runtime functions have an underscore in front of the name. */ \
if (inline_runtime_functions) { \
- name = factory->NewStringFromAscii( \
- Vector<const char>("_" #Name, StrLength("_" #Name))); \
+ name = factory->NewStringFromStaticAscii("_" #Name); \
} else { \
- name = factory->NewStringFromAscii( \
- Vector<const char>(#Name, StrLength(#Name))); \
+ name = factory->NewStringFromStaticAscii(#Name); \
} \
Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
pair_elements->set(0, *name); \
@@ -14743,7 +14701,7 @@
ASSERT(args.length() == 1);
if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
- JSReceiver* obj = JSReceiver::cast(args[0]);
+ CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
if (obj->IsJSGlobalProxy()) {
Object* proto = obj->GetPrototype();
if (proto->IsNull()) return isolate->heap()->false_value();
@@ -14825,7 +14783,7 @@
CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
ASSERT(object->map()->is_access_check_needed());
- Handle<Object> key = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
SaveContext save(isolate);
isolate->set_context(observer->context());
if (!isolate->MayNamedAccess(
@@ -14988,6 +14946,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) {
+ ASSERT(args.length() == 0);
return Smi::FromInt(Smi::kMaxValue);
}
diff --git a/src/scanner.cc b/src/scanner.cc
index 67211e0..fe75010 100644
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -1118,13 +1118,19 @@
Handle<String> Scanner::AllocateNextLiteralString(Isolate* isolate,
PretenureFlag tenured) {
+ MaybeHandle<String> maybe_result;
if (is_next_literal_one_byte()) {
- return isolate->factory()->NewStringFromOneByte(
- Vector<const uint8_t>::cast(next_literal_one_byte_string()), tenured);
+ maybe_result = isolate->factory()->NewStringFromOneByte(
+ next_literal_one_byte_string(), tenured);
} else {
- return isolate->factory()->NewStringFromTwoByte(
- next_literal_two_byte_string(), tenured);
+ maybe_result = isolate->factory()->NewStringFromTwoByte(
+ next_literal_two_byte_string(), tenured);
}
+ // TODO(ishell): Temporarily returning null handle from here. I will proceed
+ // with maybehandlification in next CLs.
+ Handle<String> result;
+ if (!maybe_result.ToHandle(&result)) return Handle<String>();
+ return result;
}
diff --git a/src/spaces.cc b/src/spaces.cc
index dfa9cea..996afe4 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -27,6 +27,7 @@
#include "v8.h"
+#include "full-codegen.h"
#include "macro-assembler.h"
#include "mark-compact.h"
#include "msan.h"
@@ -1083,7 +1084,7 @@
// upgraded to handle small pages.
size = AreaSize();
} else {
- size = 480 * KB;
+ size = 480 * KB * FullCodeGenerator::kBootCodeSizeMultiplier / 100;
}
break;
default:
diff --git a/src/string-stream.cc b/src/string-stream.cc
index 93eb222..e9795ad 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -265,8 +265,14 @@
Handle<String> StringStream::ToString(Isolate* isolate) {
- return isolate->factory()->NewStringFromUtf8(
+ MaybeHandle<String> maybe_result = isolate->factory()->NewStringFromUtf8(
Vector<const char>(buffer_, length_));
+
+ // TODO(ishell): Temporarily returning null handle from here. I will proceed
+ // with maybehandlification in next CLs.
+ Handle<String> result;
+ if (!maybe_result.ToHandle(&result)) return Handle<String>();
+ return result;
}
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 91d31ea..5f3a74c 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -499,7 +499,7 @@
PropertyCallbackArguments
custom_args(isolate, callback->data(), receiver, holder);
custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *value;
}
@@ -539,7 +539,7 @@
HandleScope scope(isolate);
v8::Handle<v8::Value> r =
callback_args.Call(getter, v8::Utils::ToLocal(name));
- RETURN_IF_SCHEDULED_EXCEPTION(isolate);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (!r.IsEmpty()) {
Handle<Object> result = v8::Utils::OpenHandle(*r);
result->VerifyApiCallResultType();
diff --git a/src/types.cc b/src/types.cc
index f359362..394f772 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -359,6 +359,17 @@
}
+// Check if this contains only (currently) stable classes.
+template<class Config>
+bool TypeImpl<Config>::NowStable() {
+ DisallowHeapAllocation no_allocation;
+ for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
+ if (!it.Current()->is_stable()) return false;
+ }
+ return true;
+}
+
+
// Check this overlaps that.
template<class Config>
bool TypeImpl<Config>::Maybe(TypeImpl* that) {
diff --git a/src/types.h b/src/types.h
index 3fb5927..5ca3a81 100644
--- a/src/types.h
+++ b/src/types.h
@@ -321,6 +321,8 @@
inline bool NowContains(i::Object* val);
bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
+ bool NowStable();
+
bool IsClass() { return Config::is_class(this); }
bool IsConstant() { return Config::is_constant(this); }
bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); }
diff --git a/src/v8conversions.h b/src/v8conversions.h
index b38dde7..eb315b1 100644
--- a/src/v8conversions.h
+++ b/src/v8conversions.h
@@ -75,9 +75,8 @@
SealHandleScope shs(isolate);
if (number->IsSmi()) {
int value = Smi::cast(number)->value();
- ASSERT(
- static_cast<unsigned>(Smi::kMaxValue)
- <= std::numeric_limits<size_t>::max());
+ ASSERT(static_cast<unsigned>(Smi::kMaxValue)
+ <= std::numeric_limits<size_t>::max());
if (value >= 0) {
*result = static_cast<size_t>(value);
return true;
diff --git a/src/version.cc b/src/version.cc
index 18db5c3..5852e5c 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -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 18
-#define PATCH_LEVEL 1
+#define BUILD_NUMBER 19
+#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
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 5803ad7..19e7b53 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1340,7 +1340,8 @@
__ subp(rcx, rdx);
// Make rdx the space we need for the array when it is unrolled onto the
// stack.
- __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2);
+ __ movp(rdx, rbx);
+ __ shlp(rdx, Immediate(kPointerSizeLog2));
// Check if the arguments will overflow the stack.
__ cmpp(rcx, rdx);
__ j(less_equal, stack_overflow); // Signed comparison.
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 11699e9..541d145 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -3620,202 +3620,6 @@
}
-void ArrayPushStub::Generate(MacroAssembler* masm) {
- int argc = arguments_count();
-
- StackArgumentsAccessor args(rsp, argc);
- if (argc == 0) {
- // Noop, return the length.
- __ movp(rax, FieldOperand(rdx, JSArray::kLengthOffset));
- __ ret((argc + 1) * kPointerSize);
- return;
- }
-
- Isolate* isolate = masm->isolate();
-
- if (argc != 1) {
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- Label call_builtin, attempt_to_grow_elements, with_write_barrier;
-
- // Get the elements array of the object.
- __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- // Check that the elements are in fast mode and writable.
- __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset),
- isolate->factory()->fixed_array_map());
- __ j(not_equal, &call_builtin);
- }
-
- // Get the array's length into rax and calculate new length.
- __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
- STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
- __ addl(rax, Immediate(argc));
-
- // Get the elements' length into rcx.
- __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
-
- // Check if we could survive without allocation.
- __ cmpl(rax, rcx);
-
- if (IsFastSmiOrObjectElementsKind(elements_kind())) {
- __ j(greater, &attempt_to_grow_elements);
-
- // Check if value is a smi.
- __ movp(rcx, args.GetArgumentOperand(1));
- __ JumpIfNotSmi(rcx, &with_write_barrier);
-
- // Store the value.
- __ movp(FieldOperand(rdi,
- rax,
- times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize),
- rcx);
- } else {
- __ j(greater, &call_builtin);
-
- __ movp(rcx, args.GetArgumentOperand(1));
- __ StoreNumberToDoubleElements(
- rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
- }
-
- // Save new length.
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- __ Integer32ToSmi(rax, rax); // Return new length as smi.
- __ ret((argc + 1) * kPointerSize);
-
- if (IsFastDoubleElementsKind(elements_kind())) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ bind(&with_write_barrier);
-
- if (IsFastSmiElementsKind(elements_kind())) {
- if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
-
- __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset),
- isolate->factory()->heap_number_map());
- __ j(equal, &call_builtin);
-
- ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
- ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
- __ movp(rbx, ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX));
- __ movp(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
- __ movp(rbx, ContextOperand(rbx, Context::JS_ARRAY_MAPS_INDEX));
- const int header_size = FixedArrayBase::kHeaderSize;
- // Verify that the object can be transitioned in place.
- const int origin_offset = header_size + elements_kind() * kPointerSize;
- __ movp(rdi, FieldOperand(rbx, origin_offset));
- __ cmpp(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
- __ j(not_equal, &call_builtin);
-
- const int target_offset = header_size + target_kind * kPointerSize;
- __ movp(rbx, FieldOperand(rbx, target_offset));
- ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
- masm, DONT_TRACK_ALLOCATION_SITE, NULL);
- __ movp(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
- }
-
- // Save new length.
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- // Store the value.
- __ leap(rdx, FieldOperand(rdi,
- rax, times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ movp(Operand(rdx, 0), rcx);
-
- __ RecordWrite(rdi, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
-
- __ Integer32ToSmi(rax, rax); // Return new length as smi.
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&attempt_to_grow_elements);
- if (!FLAG_inline_new) {
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
- return;
- }
-
- __ movp(rbx, args.GetArgumentOperand(1));
- // Growing elements that are SMI-only requires special handling in case the
- // new element is non-Smi. For now, delegate to the builtin.
- Label no_fast_elements_check;
- __ JumpIfSmi(rbx, &no_fast_elements_check);
- __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
- __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
- __ bind(&no_fast_elements_check);
-
- ExternalReference new_space_allocation_top =
- ExternalReference::new_space_allocation_top_address(isolate);
- ExternalReference new_space_allocation_limit =
- ExternalReference::new_space_allocation_limit_address(isolate);
-
- const int kAllocationDelta = 4;
- ASSERT(kAllocationDelta >= argc);
- // Load top.
- __ Load(rcx, new_space_allocation_top);
-
- // Check if it's the end of elements.
- __ leap(rdx, FieldOperand(rdi,
- rax, times_pointer_size,
- FixedArray::kHeaderSize - argc * kPointerSize));
- __ cmpp(rdx, rcx);
- __ j(not_equal, &call_builtin);
- __ addp(rcx, Immediate(kAllocationDelta * kPointerSize));
- Operand limit_operand = masm->ExternalOperand(new_space_allocation_limit);
- __ cmpp(rcx, limit_operand);
- __ j(above, &call_builtin);
-
- // We fit and could grow elements.
- __ Store(new_space_allocation_top, rcx);
-
- // Push the argument...
- __ movp(Operand(rdx, 0), rbx);
- // ... and fill the rest with holes.
- __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
- for (int i = 1; i < kAllocationDelta; i++) {
- __ movp(Operand(rdx, i * kPointerSize), kScratchRegister);
- }
-
- if (IsFastObjectElementsKind(elements_kind())) {
- // We know the elements array is in new space so we don't need the
- // remembered set, but we just pushed a value onto it so we may have to tell
- // the incremental marker to rescan the object that we just grew. We don't
- // need to worry about the holes because they are in old space and already
- // marked black.
- __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
- }
-
- // Restore receiver to rdx as finish sequence assumes it's here.
- __ movp(rdx, args.GetReceiverOperand());
-
- // Increment element's and array's sizes.
- __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
- Smi::FromInt(kAllocationDelta));
-
- // Make new length a smi before returning it.
- __ Integer32ToSmi(rax, rax);
- __ movp(FieldOperand(rdx, JSArray::kLengthOffset), rax);
-
- __ ret((argc + 1) * kPointerSize);
-
- __ bind(&call_builtin);
- __ TailCallExternalReference(
- ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
-}
-
-
void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rdx : left
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 0981114..93121a0 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -494,13 +494,21 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -645,13 +653,21 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.