diff options
Diffstat (limited to 'src/3rdparty/v8/src/builtins.cc')
-rw-r--r-- | src/3rdparty/v8/src/builtins.cc | 154 |
1 files changed, 105 insertions, 49 deletions
diff --git a/src/3rdparty/v8/src/builtins.cc b/src/3rdparty/v8/src/builtins.cc index 84a0c3d..620e4b3 100644 --- a/src/3rdparty/v8/src/builtins.cc +++ b/src/3rdparty/v8/src/builtins.cc @@ -35,6 +35,7 @@ #include "ic-inl.h" #include "heap-profiler.h" #include "mark-compact.h" +#include "stub-cache.h" #include "vm-state-inl.h" namespace v8 { @@ -199,10 +200,13 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, array->set_length(Smi::FromInt(0)); array->set_elements(heap->empty_fixed_array()); if (!FLAG_smi_only_arrays) { - Context* global_context = isolate->context()->global_context(); - if (array->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && - !global_context->object_js_array_map()->IsUndefined()) { - array->set_map(Map::cast(global_context->object_js_array_map())); + Context* native_context = isolate->context()->native_context(); + if (array->GetElementsKind() == GetInitialFastElementsKind() && + !native_context->js_array_maps()->IsUndefined()) { + FixedArray* map_array = + FixedArray::cast(native_context->js_array_maps()); + array->set_map(Map::cast(map_array-> + get(TERMINAL_FAST_ELEMENTS_KIND))); } } } else { @@ -222,6 +226,13 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len); if (!maybe_obj->ToObject(&fixed_array)) return maybe_obj; } + ElementsKind elements_kind = array->GetElementsKind(); + if (!IsFastHoleyElementsKind(elements_kind)) { + elements_kind = GetHoleyElementsKind(elements_kind); + MaybeObject* maybe_array = + array->TransitionElementsKind(elements_kind); + if (maybe_array->IsFailure()) return maybe_array; + } // We do not use SetContent to skip the unnecessary elements type check. array->set_elements(FixedArray::cast(fixed_array)); array->set_length(Smi::cast(obj)); @@ -250,7 +261,7 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, // Allocate an appropriately typed elements array. MaybeObject* maybe_elms; ElementsKind elements_kind = array->GetElementsKind(); - if (elements_kind == FAST_DOUBLE_ELEMENTS) { + if (IsFastDoubleElementsKind(elements_kind)) { maybe_elms = heap->AllocateUninitializedFixedDoubleArray( number_of_elements); } else { @@ -261,13 +272,15 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, // Fill in the content switch (array->GetElementsKind()) { - case FAST_SMI_ONLY_ELEMENTS: { + case FAST_HOLEY_SMI_ELEMENTS: + case FAST_SMI_ELEMENTS: { FixedArray* smi_elms = FixedArray::cast(elms); for (int index = 0; index < number_of_elements; index++) { smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER); } break; } + case FAST_HOLEY_ELEMENTS: case FAST_ELEMENTS: { AssertNoAllocation no_gc; WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); @@ -277,6 +290,7 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, } break; } + case FAST_HOLEY_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS: { FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms); for (int index = 0; index < number_of_elements; index++) { @@ -299,7 +313,7 @@ BUILTIN(InternalArrayCodeGeneric) { return ArrayCodeGenericCommon( &args, isolate, - isolate->context()->global_context()->internal_array_function()); + isolate->context()->native_context()->internal_array_function()); } @@ -307,7 +321,7 @@ BUILTIN(ArrayCodeGeneric) { return ArrayCodeGenericCommon( &args, isolate, - isolate->context()->global_context()->array_function()); + isolate->context()->native_context()->array_function()); } @@ -389,7 +403,7 @@ static FixedArray* LeftTrimFixedArray(Heap* heap, static bool ArrayPrototypeHasNoElements(Heap* heap, - Context* global_context, + Context* native_context, JSObject* array_proto) { // This method depends on non writability of Object and Array prototype // fields. @@ -398,7 +412,7 @@ static bool ArrayPrototypeHasNoElements(Heap* heap, Object* proto = array_proto->GetPrototype(); if (proto == heap->null_value()) return false; array_proto = JSObject::cast(proto); - if (array_proto != global_context->initial_object_prototype()) return false; + if (array_proto != native_context->initial_object_prototype()) return false; if (array_proto->elements() != heap->empty_fixed_array()) return false; return array_proto->GetPrototype()->IsNull(); } @@ -412,7 +426,7 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements( HeapObject* elms = array->elements(); Map* map = elms->map(); if (map == heap->fixed_array_map()) { - if (args == NULL || array->HasFastElements()) return elms; + if (args == NULL || array->HasFastObjectElements()) return elms; if (array->HasFastDoubleElements()) { ASSERT(elms == heap->empty_fixed_array()); MaybeObject* maybe_transition = @@ -422,7 +436,7 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements( } } else if (map == heap->fixed_cow_array_map()) { MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); - if (args == NULL || array->HasFastElements() || + if (args == NULL || array->HasFastObjectElements() || maybe_writable_result->IsFailure()) { return maybe_writable_result; } @@ -448,11 +462,11 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements( static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, JSArray* receiver) { if (!FLAG_clever_optimizations) return false; - Context* global_context = heap->isolate()->context()->global_context(); + Context* native_context = heap->isolate()->context()->native_context(); JSObject* array_proto = - JSObject::cast(global_context->array_function()->prototype()); + JSObject::cast(native_context->array_function()->prototype()); return receiver->GetPrototype() == array_proto && - ArrayPrototypeHasNoElements(heap, global_context, array_proto); + ArrayPrototypeHasNoElements(heap, native_context, array_proto); } @@ -463,7 +477,7 @@ MUST_USE_RESULT static MaybeObject* CallJsBuiltin( HandleScope handleScope(isolate); Handle<Object> js_builtin = - GetProperty(Handle<JSObject>(isolate->global_context()->builtins()), + GetProperty(Handle<JSObject>(isolate->native_context()->builtins()), name); Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin); int argc = args.length() - 1; @@ -496,6 +510,10 @@ BUILTIN(ArrayPush) { FixedArray* elms = FixedArray::cast(elms_obj); JSArray* array = JSArray::cast(receiver); + if (FLAG_harmony_observation && array->map()->is_observed()) { + return CallJsBuiltin(isolate, "ArrayPush", args); + } + int len = Smi::cast(array->length())->value(); int to_add = args.length() - 1; if (to_add == 0) { @@ -516,8 +534,8 @@ BUILTIN(ArrayPush) { } FixedArray* new_elms = FixedArray::cast(obj); - CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0, - new_elms, FAST_ELEMENTS, 0, len); + ElementsKind kind = array->GetElementsKind(); + CopyObjectToObjectElements(elms, kind, 0, new_elms, kind, 0, len); FillWithHoles(heap, new_elms, new_length, capacity); elms = new_elms; @@ -552,11 +570,15 @@ BUILTIN(ArrayPop) { FixedArray* elms = FixedArray::cast(elms_obj); JSArray* array = JSArray::cast(receiver); + if (FLAG_harmony_observation && array->map()->is_observed()) { + return CallJsBuiltin(isolate, "ArrayPop", args); + } + int len = Smi::cast(array->length())->value(); if (len == 0) return heap->undefined_value(); // Get top element - MaybeObject* top = elms->get(len - 1); + Object* top = elms->get(len - 1); // Set the length. array->set_length(Smi::FromInt(len - 1)); @@ -567,9 +589,7 @@ BUILTIN(ArrayPop) { return top; } - top = array->GetPrototype()->GetElement(len - 1); - - return top; + return array->GetPrototype()->GetElement(len - 1); } @@ -588,7 +608,11 @@ BUILTIN(ArrayShift) { } FixedArray* elms = FixedArray::cast(elms_obj); JSArray* array = JSArray::cast(receiver); - ASSERT(array->HasFastTypeElements()); + ASSERT(array->HasFastSmiOrObjectElements()); + + if (FLAG_harmony_observation && array->map()->is_observed()) { + return CallJsBuiltin(isolate, "ArrayShift", args); + } int len = Smi::cast(array->length())->value(); if (len == 0) return heap->undefined_value(); @@ -630,7 +654,11 @@ BUILTIN(ArrayUnshift) { } FixedArray* elms = FixedArray::cast(elms_obj); JSArray* array = JSArray::cast(receiver); - ASSERT(array->HasFastTypeElements()); + ASSERT(array->HasFastSmiOrObjectElements()); + + if (FLAG_harmony_observation && array->map()->is_observed()) { + return CallJsBuiltin(isolate, "ArrayUnshift", args); + } int len = Smi::cast(array->length())->value(); int to_add = args.length() - 1; @@ -652,8 +680,8 @@ BUILTIN(ArrayUnshift) { if (!maybe_obj->ToObject(&obj)) return maybe_obj; } FixedArray* new_elms = FixedArray::cast(obj); - CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0, - new_elms, FAST_ELEMENTS, to_add, len); + ElementsKind kind = array->GetElementsKind(); + CopyObjectToObjectElements(elms, kind, 0, new_elms, kind, to_add, len); FillWithHoles(heap, new_elms, new_length, capacity); elms = new_elms; array->set_elements(elms); @@ -682,7 +710,7 @@ BUILTIN(ArraySlice) { int len = -1; if (receiver->IsJSArray()) { JSArray* array = JSArray::cast(receiver); - if (!array->HasFastTypeElements() || + if (!array->HasFastSmiOrObjectElements() || !IsJSArrayFastElementMovingAllowed(heap, array)) { return CallJsBuiltin(isolate, "ArraySlice", args); } @@ -693,12 +721,12 @@ BUILTIN(ArraySlice) { // Array.slice(arguments, ...) is quite a common idiom (notably more // than 50% of invocations in Web apps). Treat it in C++ as well. Map* arguments_map = - isolate->context()->global_context()->arguments_boilerplate()->map(); + isolate->context()->native_context()->arguments_boilerplate()->map(); bool is_arguments_object_with_fast_elements = receiver->IsJSObject() && JSObject::cast(receiver)->map() == arguments_map - && JSObject::cast(receiver)->HasFastTypeElements(); + && JSObject::cast(receiver)->HasFastSmiOrObjectElements(); if (!is_arguments_object_with_fast_elements) { return CallJsBuiltin(isolate, "ArraySlice", args); } @@ -763,9 +791,9 @@ BUILTIN(ArraySlice) { JSArray* result_array; if (!maybe_array->To(&result_array)) return maybe_array; - CopyObjectToObjectElements(elms, FAST_ELEMENTS, k, + CopyObjectToObjectElements(elms, elements_kind, k, FixedArray::cast(result_array->elements()), - FAST_ELEMENTS, 0, result_len); + elements_kind, 0, result_len); return result_array; } @@ -786,7 +814,11 @@ BUILTIN(ArraySplice) { } FixedArray* elms = FixedArray::cast(elms_obj); JSArray* array = JSArray::cast(receiver); - ASSERT(array->HasFastTypeElements()); + ASSERT(array->HasFastSmiOrObjectElements()); + + if (FLAG_harmony_observation && array->map()->is_observed()) { + return CallJsBuiltin(isolate, "ArraySplice", args); + } int len = Smi::cast(array->length())->value(); @@ -837,9 +869,9 @@ BUILTIN(ArraySplice) { { // Fill newly created array. - CopyObjectToObjectElements(elms, FAST_ELEMENTS, actual_start, + CopyObjectToObjectElements(elms, elements_kind, actual_start, FixedArray::cast(result_array->elements()), - FAST_ELEMENTS, 0, actual_delete_count); + elements_kind, 0, actual_delete_count); } int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; @@ -888,12 +920,13 @@ BUILTIN(ArraySplice) { { // Copy the part before actual_start as is. - CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0, - new_elms, FAST_ELEMENTS, 0, actual_start); + ElementsKind kind = array->GetElementsKind(); + CopyObjectToObjectElements(elms, kind, 0, + new_elms, kind, 0, actual_start); const int to_copy = len - actual_delete_count - actual_start; - CopyObjectToObjectElements(elms, FAST_ELEMENTS, + CopyObjectToObjectElements(elms, kind, actual_start + actual_delete_count, - new_elms, FAST_ELEMENTS, + new_elms, kind, actual_start + item_count, to_copy); } @@ -929,10 +962,10 @@ BUILTIN(ArraySplice) { BUILTIN(ArrayConcat) { Heap* heap = isolate->heap(); - Context* global_context = isolate->context()->global_context(); + Context* native_context = isolate->context()->native_context(); JSObject* array_proto = - JSObject::cast(global_context->array_function()->prototype()); - if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) { + JSObject::cast(native_context->array_function()->prototype()); + if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) { return CallJsBuiltin(isolate, "ArrayConcat", args); } @@ -940,11 +973,12 @@ BUILTIN(ArrayConcat) { // and calculating total length. int n_arguments = args.length(); int result_len = 0; - ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; + ElementsKind elements_kind = GetInitialFastElementsKind(); for (int i = 0; i < n_arguments; i++) { Object* arg = args[i]; - if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastTypeElements() - || JSArray::cast(arg)->GetPrototype() != array_proto) { + if (!arg->IsJSArray() || + !JSArray::cast(arg)->HasFastSmiOrObjectElements() || + JSArray::cast(arg)->GetPrototype() != array_proto) { return CallJsBuiltin(isolate, "ArrayConcat", args); } @@ -961,8 +995,18 @@ BUILTIN(ArrayConcat) { return CallJsBuiltin(isolate, "ArrayConcat", args); } - if (!JSArray::cast(arg)->HasFastSmiOnlyElements()) { - elements_kind = FAST_ELEMENTS; + if (!JSArray::cast(arg)->HasFastSmiElements()) { + if (IsFastSmiElementsKind(elements_kind)) { + if (IsFastHoleyElementsKind(elements_kind)) { + elements_kind = FAST_HOLEY_ELEMENTS; + } else { + elements_kind = FAST_ELEMENTS; + } + } + } + + if (JSArray::cast(arg)->HasFastHoleyElements()) { + elements_kind = GetHoleyElementsKind(elements_kind); } } @@ -982,8 +1026,8 @@ BUILTIN(ArrayConcat) { JSArray* array = JSArray::cast(args[i]); int len = Smi::cast(array->length())->value(); FixedArray* elms = FixedArray::cast(array->elements()); - CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0, - result_elms, FAST_ELEMENTS, + CopyObjectToObjectElements(elms, elements_kind, 0, + result_elms, elements_kind, start_pos, len); start_pos += len; } @@ -1123,6 +1167,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper( result = heap->undefined_value(); } else { result = *reinterpret_cast<Object**>(*value); + result->VerifyApiCallResultType(); } RETURN_IF_SCHEDULED_EXCEPTION(isolate); @@ -1199,6 +1244,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor( result = heap->undefined_value(); } else { result = *reinterpret_cast<Object**>(*value); + result->VerifyApiCallResultType(); } } // Check for exceptions and return result. @@ -1266,6 +1312,11 @@ static void Generate_LoadIC_Normal(MacroAssembler* masm) { } +static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) { + LoadStubCompiler::GenerateLoadViaGetter(masm, Handle<JSFunction>()); +} + + static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) { KeyedLoadIC::GenerateInitialize(masm); } @@ -1363,6 +1414,11 @@ static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) { } +static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { + StoreStubCompiler::GenerateStoreViaSetter(masm, Handle<JSFunction>()); +} + + static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) { KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode); } @@ -1582,7 +1638,7 @@ void Builtins::SetUp(bool create_heap_objects) { // For now we generate builtin adaptor code into a stack-allocated // buffer, before copying it into individual code objects. Be careful // with alignment, some platforms don't like unaligned code. - union { int force_alignment; byte buffer[4*KB]; } u; + union { int force_alignment; byte buffer[8*KB]; } u; // Traverse the list of builtins and generate an adaptor in a // separate code object for each one. |