| Index: src/builtins.cc
|
| ===================================================================
|
| --- src/builtins.cc (revision 6800)
|
| +++ src/builtins.cc (working copy)
|
| @@ -31,6 +31,7 @@
|
| #include "arguments.h"
|
| #include "bootstrapper.h"
|
| #include "builtins.h"
|
| +#include "gdb-jit.h"
|
| #include "ic-inl.h"
|
| #include "mark-compact.h"
|
| #include "vm-state-inl.h"
|
| @@ -372,7 +373,9 @@
|
| array_proto = JSObject::cast(array_proto->GetPrototype());
|
| ASSERT(array_proto->elements() == Heap::empty_fixed_array());
|
| // Object.prototype
|
| - array_proto = JSObject::cast(array_proto->GetPrototype());
|
| + 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->elements() != Heap::empty_fixed_array()) return false;
|
| ASSERT(array_proto->GetPrototype()->IsNull());
|
| @@ -641,15 +644,20 @@
|
| return CallJsBuiltin("ArraySlice", args);
|
| }
|
| elms = FixedArray::cast(JSObject::cast(receiver)->elements());
|
| - len = elms->length();
|
| -#ifdef DEBUG
|
| - // Arguments object by construction should have no holes, check it.
|
| - if (FLAG_enable_slow_asserts) {
|
| - for (int i = 0; i < len; i++) {
|
| - ASSERT(elms->get(i) != Heap::the_hole_value());
|
| + Object* len_obj = JSObject::cast(receiver)
|
| + ->InObjectPropertyAt(Heap::arguments_length_index);
|
| + if (!len_obj->IsSmi()) {
|
| + return CallJsBuiltin("ArraySlice", args);
|
| + }
|
| + len = Smi::cast(len_obj)->value();
|
| + if (len > elms->length()) {
|
| + return CallJsBuiltin("ArraySlice", args);
|
| + }
|
| + for (int i = 0; i < len; i++) {
|
| + if (elms->get(i) == Heap::the_hole_value()) {
|
| + return CallJsBuiltin("ArraySlice", args);
|
| }
|
| }
|
| -#endif
|
| }
|
| ASSERT(len >= 0);
|
| int n_arguments = args.length() - 1;
|
| @@ -733,35 +741,39 @@
|
|
|
| int n_arguments = args.length() - 1;
|
|
|
| - // Return empty array when no arguments are supplied.
|
| - if (n_arguments == 0) {
|
| - return AllocateEmptyJSArray();
|
| - }
|
| -
|
| int relative_start = 0;
|
| - Object* arg1 = args[1];
|
| - if (arg1->IsSmi()) {
|
| - relative_start = Smi::cast(arg1)->value();
|
| - } else if (!arg1->IsUndefined()) {
|
| - return CallJsBuiltin("ArraySplice", args);
|
| + if (n_arguments > 0) {
|
| + Object* arg1 = args[1];
|
| + if (arg1->IsSmi()) {
|
| + relative_start = Smi::cast(arg1)->value();
|
| + } else if (!arg1->IsUndefined()) {
|
| + return CallJsBuiltin("ArraySplice", args);
|
| + }
|
| }
|
| int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
|
| : Min(relative_start, len);
|
|
|
| // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
|
| - // given differently from when an undefined delete count is given.
|
| + // given as a request to delete all the elements from the start.
|
| + // And it differs from the case of undefined delete count.
|
| // This does not follow ECMA-262, but we do the same for
|
| // compatibility.
|
| - int delete_count = len;
|
| - if (n_arguments > 1) {
|
| - Object* arg2 = args[2];
|
| - if (arg2->IsSmi()) {
|
| - delete_count = Smi::cast(arg2)->value();
|
| - } else {
|
| - return CallJsBuiltin("ArraySplice", args);
|
| + int actual_delete_count;
|
| + if (n_arguments == 1) {
|
| + ASSERT(len - actual_start >= 0);
|
| + actual_delete_count = len - actual_start;
|
| + } else {
|
| + int value = 0; // ToInteger(undefined) == 0
|
| + if (n_arguments > 1) {
|
| + Object* arg2 = args[2];
|
| + if (arg2->IsSmi()) {
|
| + value = Smi::cast(arg2)->value();
|
| + } else {
|
| + return CallJsBuiltin("ArraySplice", args);
|
| + }
|
| }
|
| + actual_delete_count = Min(Max(value, 0), len - actual_start);
|
| }
|
| - int actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
|
|
|
| JSArray* result_array = NULL;
|
| if (actual_delete_count == 0) {
|
| @@ -1227,10 +1239,15 @@
|
|
|
|
|
| static void Generate_LoadIC_StringLength(MacroAssembler* masm) {
|
| - LoadIC::GenerateStringLength(masm);
|
| + LoadIC::GenerateStringLength(masm, false);
|
| }
|
|
|
|
|
| +static void Generate_LoadIC_StringWrapperLength(MacroAssembler* masm) {
|
| + LoadIC::GenerateStringLength(masm, true);
|
| +}
|
| +
|
| +
|
| static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
|
| LoadIC::GenerateFunctionPrototype(masm);
|
| }
|
| @@ -1281,44 +1298,6 @@
|
| }
|
|
|
|
|
| -static void Generate_KeyedLoadIC_ExternalByteArray(MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalByteArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalUnsignedByteArray(
|
| - MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedByteArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalShortArray(MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalShortArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalUnsignedShortArray(
|
| - MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedShortArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalIntArray(MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalIntArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalUnsignedIntArray(
|
| - MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalUnsignedIntArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedLoadIC_ExternalFloatArray(MacroAssembler* masm) {
|
| - KeyedLoadIC::GenerateExternalArray(masm, kExternalFloatArray);
|
| -}
|
| -
|
| -
|
| static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
|
| KeyedLoadIC::GeneratePreMonomorphic(masm);
|
| }
|
| @@ -1333,6 +1312,11 @@
|
| }
|
|
|
|
|
| +static void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) {
|
| + StoreIC::GenerateInitialize(masm);
|
| +}
|
| +
|
| +
|
| static void Generate_StoreIC_Miss(MacroAssembler* masm) {
|
| StoreIC::GenerateMiss(masm);
|
| }
|
| @@ -1343,64 +1327,46 @@
|
| }
|
|
|
|
|
| -static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
|
| - StoreIC::GenerateMegamorphic(masm);
|
| +static void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) {
|
| + StoreIC::GenerateNormal(masm);
|
| }
|
|
|
|
|
| -static void Generate_StoreIC_ArrayLength(MacroAssembler* masm) {
|
| - StoreIC::GenerateArrayLength(masm);
|
| +static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
|
| + StoreIC::GenerateMegamorphic(masm, StoreIC::kStoreICNonStrict);
|
| }
|
|
|
|
|
| -static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
|
| - StoreIC::GenerateGlobalProxy(masm);
|
| +static void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
|
| + StoreIC::GenerateMegamorphic(masm, StoreIC::kStoreICStrict);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateGeneric(masm);
|
| +static void Generate_StoreIC_ArrayLength(MacroAssembler* masm) {
|
| + StoreIC::GenerateArrayLength(masm);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_ExternalByteArray(MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalByteArray);
|
| +static void Generate_StoreIC_ArrayLength_Strict(MacroAssembler* masm) {
|
| + StoreIC::GenerateArrayLength(masm);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_ExternalUnsignedByteArray(
|
| - MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedByteArray);
|
| +static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
|
| + StoreIC::GenerateGlobalProxy(masm);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_ExternalShortArray(MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalShortArray);
|
| +static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
|
| + StoreIC::GenerateGlobalProxy(masm);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_ExternalUnsignedShortArray(
|
| - MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedShortArray);
|
| +static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
|
| + KeyedStoreIC::GenerateGeneric(masm);
|
| }
|
|
|
|
|
| -static void Generate_KeyedStoreIC_ExternalIntArray(MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalIntArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedStoreIC_ExternalUnsignedIntArray(
|
| - MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalUnsignedIntArray);
|
| -}
|
| -
|
| -
|
| -static void Generate_KeyedStoreIC_ExternalFloatArray(MacroAssembler* masm) {
|
| - KeyedStoreIC::GenerateExternalArray(masm, kExternalFloatArray);
|
| -}
|
| -
|
| -
|
| static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
|
| KeyedStoreIC::GenerateMiss(masm);
|
| }
|
| @@ -1508,13 +1474,13 @@
|
| extra_args \
|
| },
|
|
|
| -#define DEF_FUNCTION_PTR_A(name, kind, state) \
|
| - { FUNCTION_ADDR(Generate_##name), \
|
| - NULL, \
|
| - #name, \
|
| - name, \
|
| - Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state), \
|
| - NO_EXTRA_ARGUMENTS \
|
| +#define DEF_FUNCTION_PTR_A(name, kind, state, extra) \
|
| + { FUNCTION_ADDR(Generate_##name), \
|
| + NULL, \
|
| + #name, \
|
| + name, \
|
| + Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state, extra), \
|
| + NO_EXTRA_ARGUMENTS \
|
| },
|
|
|
| // Define array of pointers to generators and C builtin functions.
|
| @@ -1550,7 +1516,7 @@
|
| CodeDesc desc;
|
| masm.GetCode(&desc);
|
| Code::Flags flags = functions[i].flags;
|
| - Object* code = 0;
|
| + Object* code = NULL;
|
| {
|
| // During startup it's OK to always allocate and defer GC to later.
|
| // This simplifies things because we don't need to retry.
|
| @@ -1564,7 +1530,11 @@
|
| }
|
| // Log the event and add the code to the builtins array.
|
| PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
|
| - Code::cast(code), functions[i].s_name));
|
| + Code::cast(code),
|
| + functions[i].s_name));
|
| + GDBJIT(AddCode(GDBJITInterface::BUILTIN,
|
| + functions[i].s_name,
|
| + Code::cast(code)));
|
| builtins_[i] = code;
|
| #ifdef ENABLE_DISASSEMBLER
|
| if (FLAG_print_builtin_code) {
|
|
|