| Index: src/arm/stub-cache-arm.cc
|
| ===================================================================
|
| --- src/arm/stub-cache-arm.cc (revision 8618)
|
| +++ src/arm/stub-cache-arm.cc (working copy)
|
| @@ -121,7 +121,7 @@
|
|
|
| // Check that receiver is a JSObject.
|
| __ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
| - __ cmp(scratch0, Operand(FIRST_JS_OBJECT_TYPE));
|
| + __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
|
| __ b(lt, miss_label);
|
|
|
| // Load properties array.
|
| @@ -189,8 +189,7 @@
|
| ASSERT(!extra2.is(no_reg));
|
|
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(receiver, &miss);
|
|
|
| // Get the map of the receiver and compute the hash.
|
| __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset));
|
| @@ -282,8 +281,7 @@
|
| Register scratch,
|
| Label* miss_label) {
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, miss_label);
|
| + __ JumpIfSmi(receiver, miss_label);
|
|
|
| // Check that the object is a JS array.
|
| __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
|
| @@ -305,8 +303,7 @@
|
| Label* smi,
|
| Label* non_string_object) {
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, smi);
|
| + __ JumpIfSmi(receiver, smi);
|
|
|
| // Check that the object is a string.
|
| __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
| @@ -381,8 +378,7 @@
|
| Label exit;
|
|
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver_reg, Operand(kSmiTagMask));
|
| - __ b(eq, miss_label);
|
| + __ JumpIfSmi(receiver_reg, miss_label);
|
|
|
| // Check that the map of the receiver hasn't changed.
|
| __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
|
| @@ -430,6 +426,9 @@
|
| int offset = object->map()->instance_size() + (index * kPointerSize);
|
| __ str(r0, FieldMemOperand(receiver_reg, offset));
|
|
|
| + // Skip updating write barrier if storing a smi.
|
| + __ JumpIfSmi(r0, &exit);
|
| +
|
| // Update the write barrier for the array address.
|
| // Pass the now unused name_reg as a scratch register.
|
| __ mov(name_reg, r0);
|
| @@ -446,6 +445,9 @@
|
| __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
|
| __ str(r0, FieldMemOperand(scratch, offset));
|
|
|
| + // Skip updating write barrier if storing a smi.
|
| + __ JumpIfSmi(r0, &exit);
|
| +
|
| // Update the write barrier for the array address.
|
| // Ok to clobber receiver_reg and name_reg, since we return.
|
| __ mov(name_reg, r0);
|
| @@ -480,7 +482,8 @@
|
| static void GenerateCallFunction(MacroAssembler* masm,
|
| Object* object,
|
| const ParameterCount& arguments,
|
| - Label* miss) {
|
| + Label* miss,
|
| + Code::ExtraICState extra_ic_state) {
|
| // ----------- S t a t e -------------
|
| // -- r0: receiver
|
| // -- r1: function to call
|
| @@ -499,7 +502,10 @@
|
| }
|
|
|
| // Invoke the function.
|
| - __ InvokeFunction(r1, arguments, JUMP_FUNCTION);
|
| + CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
|
| + ? CALL_AS_FUNCTION
|
| + : CALL_AS_METHOD;
|
| + __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
|
| }
|
|
|
|
|
| @@ -629,10 +635,12 @@
|
| public:
|
| CallInterceptorCompiler(StubCompiler* stub_compiler,
|
| const ParameterCount& arguments,
|
| - Register name)
|
| + Register name,
|
| + Code::ExtraICState extra_ic_state)
|
| : stub_compiler_(stub_compiler),
|
| arguments_(arguments),
|
| - name_(name) {}
|
| + name_(name),
|
| + extra_ic_state_(extra_ic_state) {}
|
|
|
| MaybeObject* Compile(MacroAssembler* masm,
|
| JSObject* object,
|
| @@ -760,8 +768,11 @@
|
| arguments_.immediate());
|
| if (result->IsFailure()) return result;
|
| } else {
|
| + CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
|
| + ? CALL_AS_FUNCTION
|
| + : CALL_AS_METHOD;
|
| __ InvokeFunction(optimization.constant_function(), arguments_,
|
| - JUMP_FUNCTION);
|
| + JUMP_FUNCTION, call_kind);
|
| }
|
|
|
| // Deferred code for fast API call case---clean preallocated space.
|
| @@ -843,6 +854,7 @@
|
| StubCompiler* stub_compiler_;
|
| const ParameterCount& arguments_;
|
| Register name_;
|
| + Code::ExtraICState extra_ic_state_;
|
| };
|
|
|
|
|
| @@ -1159,8 +1171,7 @@
|
| String* name,
|
| Label* miss) {
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, miss);
|
| + __ JumpIfSmi(receiver, miss);
|
|
|
| // Check that the maps haven't changed.
|
| Register reg =
|
| @@ -1181,8 +1192,7 @@
|
| String* name,
|
| Label* miss) {
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, miss);
|
| + __ JumpIfSmi(receiver, miss);
|
|
|
| // Check that the maps haven't changed.
|
| Register reg =
|
| @@ -1206,8 +1216,7 @@
|
| String* name,
|
| Label* miss) {
|
| // Check that the receiver isn't a smi.
|
| - __ tst(receiver, Operand(kSmiTagMask));
|
| - __ b(eq, miss);
|
| + __ JumpIfSmi(receiver, miss);
|
|
|
| // Check that the maps haven't changed.
|
| Register reg =
|
| @@ -1420,8 +1429,7 @@
|
| // object which can only happen for contextual calls. In this case,
|
| // the receiver cannot be a smi.
|
| if (object != holder) {
|
| - __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(eq, miss);
|
| + __ JumpIfSmi(r0, miss);
|
| }
|
|
|
| // Check that the maps haven't changed.
|
| @@ -1443,8 +1451,7 @@
|
| // the nice side effect that multiple closures based on the same
|
| // function can all use this call IC. Before we load through the
|
| // function, we have to verify that it still is a function.
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, miss);
|
| + __ JumpIfSmi(r1, miss);
|
| __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
|
| __ b(ne, miss);
|
|
|
| @@ -1489,14 +1496,13 @@
|
| // Get the receiver of the function from the stack into r0.
|
| __ ldr(r0, MemOperand(sp, argc * kPointerSize));
|
| // Check that the receiver isn't a smi.
|
| - __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r0, &miss);
|
|
|
| // Do the right check and compute the holder register.
|
| Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss);
|
| GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
|
|
|
| - GenerateCallFunction(masm(), object, arguments(), &miss);
|
| + GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_);
|
|
|
| // Handle call cache miss.
|
| __ bind(&miss);
|
| @@ -1967,8 +1973,7 @@
|
| __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
|
|
|
| STATIC_ASSERT(kSmiTag == 0);
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r1, &miss);
|
|
|
| CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
|
| &miss);
|
| @@ -1985,8 +1990,7 @@
|
| // Check the code is a smi.
|
| Label slow;
|
| STATIC_ASSERT(kSmiTag == 0);
|
| - __ tst(code, Operand(kSmiTagMask));
|
| - __ b(ne, &slow);
|
| + __ JumpIfNotSmi(code, &slow);
|
|
|
| // Convert the smi code to uint16.
|
| __ and_(code, code, Operand(Smi::FromInt(0xffff)));
|
| @@ -2002,7 +2006,7 @@
|
| // Tail call the full function. We do not have to patch the receiver
|
| // because the function makes no use of it.
|
| __ bind(&slow);
|
| - __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
| + __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
|
|
|
| __ bind(&miss);
|
| // r2: function name.
|
| @@ -2150,7 +2154,7 @@
|
| __ bind(&slow);
|
| // Tail call the full function. We do not have to patch the receiver
|
| // because the function makes no use of it.
|
| - __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
| + __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
|
|
|
| __ bind(&miss);
|
| // r2: function name.
|
| @@ -2188,8 +2192,7 @@
|
| __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
|
|
|
| STATIC_ASSERT(kSmiTag == 0);
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r1, &miss);
|
|
|
| CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
|
| &miss);
|
| @@ -2252,7 +2255,7 @@
|
| // Tail call the full function. We do not have to patch the receiver
|
| // because the function makes no use of it.
|
| __ bind(&slow);
|
| - __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
| + __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
|
|
|
| __ bind(&miss);
|
| // r2: function name.
|
| @@ -2292,8 +2295,7 @@
|
| __ ldr(r1, MemOperand(sp, argc * kPointerSize));
|
|
|
| // Check that the receiver isn't a smi.
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss_before_stack_reserved);
|
| + __ JumpIfSmi(r1, &miss_before_stack_reserved);
|
|
|
| __ IncrementCounter(counters->call_const(), 1, r0, r3);
|
| __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
|
| @@ -2347,8 +2349,7 @@
|
|
|
| // Check that the receiver isn't a smi.
|
| if (check != NUMBER_CHECK) {
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r1, &miss);
|
| }
|
|
|
| // Make sure that it's okay not to patch the on stack receiver
|
| @@ -2381,7 +2382,7 @@
|
| } else {
|
| // Check that the object is a two-byte string or a symbol.
|
| __ CompareObjectType(r1, r3, r3, FIRST_NONSTRING_TYPE);
|
| - __ b(hs, &miss);
|
| + __ b(ge, &miss);
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(
|
| masm(), Context::STRING_FUNCTION_INDEX, r0, &miss);
|
| @@ -2398,8 +2399,7 @@
|
| } else {
|
| Label fast;
|
| // Check that the object is a smi or a heap number.
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &fast);
|
| + __ JumpIfSmi(r1, &fast);
|
| __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE);
|
| __ b(ne, &miss);
|
| __ bind(&fast);
|
| @@ -2440,7 +2440,10 @@
|
| UNREACHABLE();
|
| }
|
|
|
| - __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
|
| + CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
|
| + ? CALL_AS_FUNCTION
|
| + : CALL_AS_METHOD;
|
| + __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
|
|
|
| // Handle call cache miss.
|
| __ bind(&miss);
|
| @@ -2473,7 +2476,7 @@
|
| // Get the receiver from the stack.
|
| __ ldr(r1, MemOperand(sp, argc * kPointerSize));
|
|
|
| - CallInterceptorCompiler compiler(this, arguments(), r2);
|
| + CallInterceptorCompiler compiler(this, arguments(), r2, extra_ic_state_);
|
| MaybeObject* result = compiler.Compile(masm(),
|
| object,
|
| holder,
|
| @@ -2493,7 +2496,7 @@
|
| // Restore receiver.
|
| __ ldr(r0, MemOperand(sp, argc * kPointerSize));
|
|
|
| - GenerateCallFunction(masm(), object, arguments(), &miss);
|
| + GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_);
|
|
|
| // Handle call cache miss.
|
| __ bind(&miss);
|
| @@ -2505,13 +2508,11 @@
|
| }
|
|
|
|
|
| -MaybeObject* CallStubCompiler::CompileCallGlobal(
|
| - JSObject* object,
|
| - GlobalObject* holder,
|
| - JSGlobalPropertyCell* cell,
|
| - JSFunction* function,
|
| - String* name,
|
| - Code::ExtraICState extra_ic_state) {
|
| +MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
|
| + GlobalObject* holder,
|
| + JSGlobalPropertyCell* cell,
|
| + JSFunction* function,
|
| + String* name) {
|
| // ----------- S t a t e -------------
|
| // -- r2 : name
|
| // -- lr : return address
|
| @@ -2553,7 +2554,7 @@
|
| ASSERT(function->is_compiled());
|
| Handle<Code> code(function->code());
|
| ParameterCount expected(function->shared()->formal_parameter_count());
|
| - CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
|
| + CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
|
| ? CALL_AS_FUNCTION
|
| : CALL_AS_METHOD;
|
| if (V8::UseCrankshaft()) {
|
| @@ -2618,8 +2619,7 @@
|
| Label miss;
|
|
|
| // Check that the object isn't a smi.
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r1, &miss);
|
|
|
| // Check that the map of the object hasn't changed.
|
| __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| @@ -2666,8 +2666,7 @@
|
| Label miss;
|
|
|
| // Check that the object isn't a smi.
|
| - __ tst(r1, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r1, &miss);
|
|
|
| // Check that the map of the object hasn't changed.
|
| __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| @@ -2758,8 +2757,7 @@
|
| Label miss;
|
|
|
| // Check that receiver is not a smi.
|
| - __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r0, &miss);
|
|
|
| // Check the maps of the full prototype chain.
|
| CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss);
|
| @@ -2903,8 +2901,7 @@
|
| // object which can only happen for contextual calls. In this case,
|
| // the receiver cannot be a smi.
|
| if (object != holder) {
|
| - __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(eq, &miss);
|
| + __ JumpIfSmi(r0, &miss);
|
| }
|
|
|
| // Check that the map of the global has not changed.
|
| @@ -3114,14 +3111,15 @@
|
| }
|
|
|
|
|
| -MaybeObject* KeyedLoadStubCompiler::CompileLoadFastElement(Map* receiver_map) {
|
| +MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
|
| // ----------- S t a t e -------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| // -- r1 : receiver
|
| // -----------------------------------
|
| - MaybeObject* maybe_stub = KeyedLoadFastElementStub().TryGetCode();
|
| Code* stub;
|
| + JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
|
| + MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
|
| if (!maybe_stub->To(&stub)) return maybe_stub;
|
| __ DispatchMap(r1,
|
| r2,
|
| @@ -3205,8 +3203,7 @@
|
| }
|
|
|
|
|
| -MaybeObject* KeyedStoreStubCompiler::CompileStoreFastElement(
|
| - Map* receiver_map) {
|
| +MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
|
| // ----------- S t a t e -------------
|
| // -- r0 : value
|
| // -- r1 : key
|
| @@ -3214,10 +3211,11 @@
|
| // -- lr : return address
|
| // -- r3 : scratch
|
| // -----------------------------------
|
| + Code* stub;
|
| + JSObject::ElementsKind elements_kind = receiver_map->elements_kind();
|
| bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
|
| MaybeObject* maybe_stub =
|
| - KeyedStoreFastElementStub(is_js_array).TryGetCode();
|
| - Code* stub;
|
| + KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
|
| if (!maybe_stub->To(&stub)) return maybe_stub;
|
| __ DispatchMap(r2,
|
| r3,
|
| @@ -3291,8 +3289,7 @@
|
| // r1: constructor function
|
| // r7: undefined
|
| __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
|
| - __ tst(r2, Operand(kSmiTagMask));
|
| - __ b(eq, &generic_stub_call);
|
| + __ JumpIfSmi(r2, &generic_stub_call);
|
| __ CompareObjectType(r2, r3, r4, MAP_TYPE);
|
| __ b(ne, &generic_stub_call);
|
|
|
| @@ -3409,82 +3406,86 @@
|
| }
|
|
|
|
|
| -MaybeObject* ExternalArrayLoadStubCompiler::CompileLoad(
|
| - JSObject*receiver, ExternalArrayType array_type) {
|
| - // ----------- S t a t e -------------
|
| - // -- lr : return address
|
| - // -- r0 : key
|
| - // -- r1 : receiver
|
| +#undef __
|
| +#define __ ACCESS_MASM(masm)
|
| +
|
| +
|
| +void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
|
| + MacroAssembler* masm) {
|
| + // ---------- S t a t e --------------
|
| + // -- lr : return address
|
| + // -- r0 : key
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| - MaybeObject* maybe_stub =
|
| - KeyedLoadExternalArrayStub(array_type).TryGetCode();
|
| - Code* stub;
|
| - if (!maybe_stub->To(&stub)) return maybe_stub;
|
| - __ DispatchMap(r1,
|
| - r2,
|
| - Handle<Map>(receiver->map()),
|
| - Handle<Code>(stub),
|
| - DO_SMI_CHECK);
|
| + Label slow, miss_force_generic;
|
|
|
| - Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + Register key = r0;
|
| + Register receiver = r1;
|
|
|
| - // Return the generated code.
|
| - return GetCode();
|
| -}
|
| + __ JumpIfNotSmi(key, &miss_force_generic);
|
| + __ mov(r2, Operand(key, ASR, kSmiTagSize));
|
| + __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| + __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5);
|
| + __ Ret();
|
|
|
| + __ bind(&slow);
|
| + __ IncrementCounter(
|
| + masm->isolate()->counters()->keyed_load_external_array_slow(),
|
| + 1, r2, r3);
|
|
|
| -MaybeObject* ExternalArrayStoreStubCompiler::CompileStore(
|
| - JSObject* receiver, ExternalArrayType array_type) {
|
| - // ----------- S t a t e -------------
|
| - // -- r0 : value
|
| - // -- r1 : name
|
| - // -- r2 : receiver
|
| - // -- lr : return address
|
| + // ---------- S t a t e --------------
|
| + // -- lr : return address
|
| + // -- r0 : key
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| - MaybeObject* maybe_stub =
|
| - KeyedStoreExternalArrayStub(array_type).TryGetCode();
|
| - Code* stub;
|
| - if (!maybe_stub->To(&stub)) return maybe_stub;
|
| - __ DispatchMap(r2,
|
| - r3,
|
| - Handle<Map>(receiver->map()),
|
| - Handle<Code>(stub),
|
| - DO_SMI_CHECK);
|
| + Handle<Code> slow_ic =
|
| + masm->isolate()->builtins()->KeyedLoadIC_Slow();
|
| + __ Jump(slow_ic, RelocInfo::CODE_TARGET);
|
|
|
| - Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + // Miss case, call the runtime.
|
| + __ bind(&miss_force_generic);
|
|
|
| - return GetCode();
|
| + // ---------- S t a t e --------------
|
| + // -- lr : return address
|
| + // -- r0 : key
|
| + // -- r1 : receiver
|
| + // -----------------------------------
|
| +
|
| + Handle<Code> miss_ic =
|
| + masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| + __ Jump(miss_ic, RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM(masm)
|
| -
|
| -
|
| -static bool IsElementTypeSigned(ExternalArrayType array_type) {
|
| - switch (array_type) {
|
| - case kExternalByteArray:
|
| - case kExternalShortArray:
|
| - case kExternalIntArray:
|
| +static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) {
|
| + switch (elements_kind) {
|
| + case JSObject::EXTERNAL_BYTE_ELEMENTS:
|
| + case JSObject::EXTERNAL_SHORT_ELEMENTS:
|
| + case JSObject::EXTERNAL_INT_ELEMENTS:
|
| return true;
|
|
|
| - case kExternalUnsignedByteArray:
|
| - case kExternalUnsignedShortArray:
|
| - case kExternalUnsignedIntArray:
|
| + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| + case JSObject::EXTERNAL_PIXEL_ELEMENTS:
|
| return false;
|
|
|
| - default:
|
| + case JSObject::EXTERNAL_FLOAT_ELEMENTS:
|
| + case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
|
| + case JSObject::FAST_ELEMENTS:
|
| + case JSObject::FAST_DOUBLE_ELEMENTS:
|
| + case JSObject::DICTIONARY_ELEMENTS:
|
| + case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| return false;
|
| }
|
| + return false;
|
| }
|
|
|
|
|
| void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
| MacroAssembler* masm,
|
| - ExternalArrayType array_type) {
|
| + JSObject::ElementsKind elements_kind) {
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| @@ -3518,25 +3519,25 @@
|
| ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
|
|
|
| Register value = r2;
|
| - switch (array_type) {
|
| - case kExternalByteArray:
|
| + switch (elements_kind) {
|
| + case JSObject::EXTERNAL_BYTE_ELEMENTS:
|
| __ ldrsb(value, MemOperand(r3, key, LSR, 1));
|
| break;
|
| - case kExternalPixelArray:
|
| - case kExternalUnsignedByteArray:
|
| + case JSObject::EXTERNAL_PIXEL_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| __ ldrb(value, MemOperand(r3, key, LSR, 1));
|
| break;
|
| - case kExternalShortArray:
|
| + case JSObject::EXTERNAL_SHORT_ELEMENTS:
|
| __ ldrsh(value, MemOperand(r3, key, LSL, 0));
|
| break;
|
| - case kExternalUnsignedShortArray:
|
| + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| __ ldrh(value, MemOperand(r3, key, LSL, 0));
|
| break;
|
| - case kExternalIntArray:
|
| - case kExternalUnsignedIntArray:
|
| + case JSObject::EXTERNAL_INT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| __ ldr(value, MemOperand(r3, key, LSL, 1));
|
| break;
|
| - case kExternalFloatArray:
|
| + case JSObject::EXTERNAL_FLOAT_ELEMENTS:
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| __ add(r2, r3, Operand(key, LSL, 1));
|
| @@ -3545,7 +3546,7 @@
|
| __ ldr(value, MemOperand(r3, key, LSL, 1));
|
| }
|
| break;
|
| - case kExternalDoubleArray:
|
| + case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| __ add(r2, r3, Operand(key, LSL, 2));
|
| @@ -3557,7 +3558,10 @@
|
| __ ldr(r3, MemOperand(r4, Register::kSizeInBytes));
|
| }
|
| break;
|
| - default:
|
| + case JSObject::FAST_ELEMENTS:
|
| + case JSObject::FAST_DOUBLE_ELEMENTS:
|
| + case JSObject::DICTIONARY_ELEMENTS:
|
| + case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| break;
|
| }
|
| @@ -3571,7 +3575,7 @@
|
| // d0: value (if VFP3 is supported)
|
| // r2/r3: value (if VFP3 is not supported)
|
|
|
| - if (array_type == kExternalIntArray) {
|
| + if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) {
|
| // For the Int and UnsignedInt array types, we need to see whether
|
| // the value can be represented in a Smi. If not, we need to convert
|
| // it to a HeapNumber.
|
| @@ -3615,7 +3619,7 @@
|
| __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
|
| __ Ret();
|
| }
|
| - } else if (array_type == kExternalUnsignedIntArray) {
|
| + } else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
|
| // The test is different for unsigned int values. Since we need
|
| // the value to be in the range of a positive smi, we can't
|
| // handle either of the top two bits being set in the value.
|
| @@ -3680,7 +3684,7 @@
|
| __ mov(r0, r4);
|
| __ Ret();
|
| }
|
| - } else if (array_type == kExternalFloatArray) {
|
| + } else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
|
| // For the floating-point array type, we need to always allocate a
|
| // HeapNumber.
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| @@ -3750,7 +3754,7 @@
|
| __ mov(r0, r3);
|
| __ Ret();
|
| }
|
| - } else if (array_type == kExternalDoubleArray) {
|
| + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| // Allocate a HeapNumber for the result. Don't use r0 and r1 as
|
| @@ -3807,7 +3811,7 @@
|
|
|
| void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| MacroAssembler* masm,
|
| - ExternalArrayType array_type) {
|
| + JSObject::ElementsKind elements_kind) {
|
| // ---------- S t a t e --------------
|
| // -- r0 : value
|
| // -- r1 : key
|
| @@ -3841,7 +3845,7 @@
|
| // runtime for all other kinds of values.
|
| // r3: external array.
|
| // r4: key (integer).
|
| - if (array_type == kExternalPixelArray) {
|
| + if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
|
| // Double to pixel conversion is only implemented in the runtime for now.
|
| __ JumpIfNotSmi(value, &slow);
|
| } else {
|
| @@ -3853,29 +3857,29 @@
|
| // r3: base pointer of external storage.
|
| // r4: key (integer).
|
| // r5: value (integer).
|
| - switch (array_type) {
|
| - case kExternalPixelArray:
|
| + switch (elements_kind) {
|
| + case JSObject::EXTERNAL_PIXEL_ELEMENTS:
|
| // Clamp the value to [0..255].
|
| __ Usat(r5, 8, Operand(r5));
|
| __ strb(r5, MemOperand(r3, r4, LSL, 0));
|
| break;
|
| - case kExternalByteArray:
|
| - case kExternalUnsignedByteArray:
|
| + case JSObject::EXTERNAL_BYTE_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| __ strb(r5, MemOperand(r3, r4, LSL, 0));
|
| break;
|
| - case kExternalShortArray:
|
| - case kExternalUnsignedShortArray:
|
| + case JSObject::EXTERNAL_SHORT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| __ strh(r5, MemOperand(r3, r4, LSL, 1));
|
| break;
|
| - case kExternalIntArray:
|
| - case kExternalUnsignedIntArray:
|
| + case JSObject::EXTERNAL_INT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| __ str(r5, MemOperand(r3, r4, LSL, 2));
|
| break;
|
| - case kExternalFloatArray:
|
| + case JSObject::EXTERNAL_FLOAT_ELEMENTS:
|
| // Perform int-to-float conversion and store to memory.
|
| StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
|
| break;
|
| - case kExternalDoubleArray:
|
| + case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
|
| __ add(r3, r3, Operand(r4, LSL, 3));
|
| // r3: effective address of the double element
|
| FloatingPointHelper::Destination destination;
|
| @@ -3896,7 +3900,10 @@
|
| __ str(r7, MemOperand(r3, Register::kSizeInBytes));
|
| }
|
| break;
|
| - default:
|
| + case JSObject::FAST_ELEMENTS:
|
| + case JSObject::FAST_DOUBLE_ELEMENTS:
|
| + case JSObject::DICTIONARY_ELEMENTS:
|
| + case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| break;
|
| }
|
| @@ -3904,7 +3911,7 @@
|
| // Entry registers are intact, r0 holds the value which is the return value.
|
| __ Ret();
|
|
|
| - if (array_type != kExternalPixelArray) {
|
| + if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
|
| // r3: external array.
|
| // r4: index (integer).
|
| __ bind(&check_heap_number);
|
| @@ -3922,7 +3929,7 @@
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
|
|
| - if (array_type == kExternalFloatArray) {
|
| + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
|
| // vldr requires offset to be a multiple of 4 so we can not
|
| // include -kHeapObjectTag into it.
|
| __ sub(r5, r0, Operand(kHeapObjectTag));
|
| @@ -3930,48 +3937,38 @@
|
| __ add(r5, r3, Operand(r4, LSL, 2));
|
| __ vcvt_f32_f64(s0, d0);
|
| __ vstr(s0, r5, 0);
|
| - } else if (array_type == kExternalDoubleArray) {
|
| + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
|
| __ sub(r5, r0, Operand(kHeapObjectTag));
|
| __ vldr(d0, r5, HeapNumber::kValueOffset);
|
| __ add(r5, r3, Operand(r4, LSL, 3));
|
| __ vstr(d0, r5, 0);
|
| } else {
|
| - // Need to perform float-to-int conversion.
|
| - // Test for NaN or infinity (both give zero).
|
| - __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset));
|
| -
|
| // Hoisted load. vldr requires offset to be a multiple of 4 so we can
|
| // not include -kHeapObjectTag into it.
|
| __ sub(r5, value, Operand(kHeapObjectTag));
|
| __ vldr(d0, r5, HeapNumber::kValueOffset);
|
| + __ EmitECMATruncate(r5, d0, s2, r6, r7, r9);
|
|
|
| - __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
|
| - // NaNs and Infinities have all-one exponents so they sign extend to -1.
|
| - __ cmp(r6, Operand(-1));
|
| - __ mov(r5, Operand(0), LeaveCC, eq);
|
| -
|
| - // Not infinity or NaN simply convert to int.
|
| - if (IsElementTypeSigned(array_type)) {
|
| - __ vcvt_s32_f64(s0, d0, kDefaultRoundToZero, ne);
|
| - } else {
|
| - __ vcvt_u32_f64(s0, d0, kDefaultRoundToZero, ne);
|
| - }
|
| - __ vmov(r5, s0, ne);
|
| -
|
| - switch (array_type) {
|
| - case kExternalByteArray:
|
| - case kExternalUnsignedByteArray:
|
| + switch (elements_kind) {
|
| + case JSObject::EXTERNAL_BYTE_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| __ strb(r5, MemOperand(r3, r4, LSL, 0));
|
| break;
|
| - case kExternalShortArray:
|
| - case kExternalUnsignedShortArray:
|
| + case JSObject::EXTERNAL_SHORT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| __ strh(r5, MemOperand(r3, r4, LSL, 1));
|
| break;
|
| - case kExternalIntArray:
|
| - case kExternalUnsignedIntArray:
|
| + case JSObject::EXTERNAL_INT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| __ str(r5, MemOperand(r3, r4, LSL, 2));
|
| break;
|
| - default:
|
| + case JSObject::EXTERNAL_PIXEL_ELEMENTS:
|
| + case JSObject::EXTERNAL_FLOAT_ELEMENTS:
|
| + case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
|
| + case JSObject::FAST_ELEMENTS:
|
| + case JSObject::FAST_DOUBLE_ELEMENTS:
|
| + case JSObject::DICTIONARY_ELEMENTS:
|
| + case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| break;
|
| }
|
| @@ -3985,7 +3982,7 @@
|
| __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
|
| __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
|
|
|
| - if (array_type == kExternalFloatArray) {
|
| + if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
|
| Label done, nan_or_infinity_or_zero;
|
| static const int kMantissaInHiWordShift =
|
| kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
|
| @@ -4037,14 +4034,14 @@
|
| __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
|
| __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
|
| __ b(&done);
|
| - } else if (array_type == kExternalDoubleArray) {
|
| + } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
|
| __ add(r7, r3, Operand(r4, LSL, 3));
|
| // r7: effective address of destination element.
|
| __ str(r6, MemOperand(r7, 0));
|
| __ str(r5, MemOperand(r7, Register::kSizeInBytes));
|
| __ Ret();
|
| } else {
|
| - bool is_signed_type = IsElementTypeSigned(array_type);
|
| + bool is_signed_type = IsElementTypeSigned(elements_kind);
|
| int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt;
|
| int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000;
|
|
|
| @@ -4091,20 +4088,26 @@
|
| __ rsb(r5, r5, Operand(0, RelocInfo::NONE), LeaveCC, ne);
|
|
|
| __ bind(&done);
|
| - switch (array_type) {
|
| - case kExternalByteArray:
|
| - case kExternalUnsignedByteArray:
|
| + switch (elements_kind) {
|
| + case JSObject::EXTERNAL_BYTE_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
|
| __ strb(r5, MemOperand(r3, r4, LSL, 0));
|
| break;
|
| - case kExternalShortArray:
|
| - case kExternalUnsignedShortArray:
|
| + case JSObject::EXTERNAL_SHORT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
|
| __ strh(r5, MemOperand(r3, r4, LSL, 1));
|
| break;
|
| - case kExternalIntArray:
|
| - case kExternalUnsignedIntArray:
|
| + case JSObject::EXTERNAL_INT_ELEMENTS:
|
| + case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
|
| __ str(r5, MemOperand(r3, r4, LSL, 2));
|
| break;
|
| - default:
|
| + case JSObject::EXTERNAL_PIXEL_ELEMENTS:
|
| + case JSObject::EXTERNAL_FLOAT_ELEMENTS:
|
| + case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
|
| + case JSObject::FAST_ELEMENTS:
|
| + case JSObject::FAST_DOUBLE_ELEMENTS:
|
| + case JSObject::DICTIONARY_ELEMENTS:
|
| + case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| break;
|
| }
|
| @@ -4205,7 +4208,7 @@
|
| // have been verified by the caller to not be a smi.
|
|
|
| // Check that the key is a smi.
|
| - __ JumpIfNotSmi(r0, &miss_force_generic);
|
| + __ JumpIfNotSmi(key_reg, &miss_force_generic);
|
|
|
| // Get the elements array and make sure it is a fast element array, not 'cow'.
|
| __ ldr(elements_reg,
|
|
|