| Index: src/x64/stub-cache-x64.cc
|
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
|
| index 0e8e74ed60de3dcfbcad660823d2850dfb3fbdf1..8c5cb9f664638ebf713fdc72e56afa5277a1aad7 100644
|
| --- a/src/x64/stub-cache-x64.cc
|
| +++ b/src/x64/stub-cache-x64.cc
|
| @@ -343,19 +343,6 @@ void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -// Load a fast property out of a holder object (src). In-object properties
|
| -// are loaded directly otherwise the property is loaded from the properties
|
| -// fixed array.
|
| -void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
|
| - Register dst,
|
| - Register src,
|
| - Handle<JSObject> holder,
|
| - PropertyIndex index) {
|
| - DoGenerateFastPropertyLoad(
|
| - masm, dst, src, index.is_inobject(holder), index.translate(holder));
|
| -}
|
| -
|
| -
|
| void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
|
| Register dst,
|
| Register src,
|
| @@ -715,28 +702,13 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| };
|
|
|
|
|
| -void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
|
| - ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
|
| - Handle<Code> code = (kind == Code::LOAD_IC)
|
| - ? masm->isolate()->builtins()->LoadIC_Miss()
|
| - : masm->isolate()->builtins()->KeyedLoadIC_Miss();
|
| - __ Jump(code, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| -void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
|
| - ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
|
| - Handle<Code> code = (kind == Code::STORE_IC)
|
| - ? masm->isolate()->builtins()->StoreIC_Miss()
|
| - : masm->isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ Jump(code, RelocInfo::CODE_TARGET);
|
| -}
|
| -
|
| -
|
| -void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
|
| - Handle<Code> code =
|
| - masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| - __ Jump(code, RelocInfo::CODE_TARGET);
|
| +void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
|
| + Label* label,
|
| + Handle<Name> name) {
|
| + if (!label->is_unused()) {
|
| + __ bind(label);
|
| + __ Move(this->name(), name);
|
| + }
|
| }
|
|
|
|
|
| @@ -749,9 +721,11 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| Handle<Name> name,
|
| Register receiver_reg,
|
| Register name_reg,
|
| + Register value_reg,
|
| Register scratch1,
|
| Register scratch2,
|
| - Label* miss_label) {
|
| + Label* miss_label,
|
| + Label* miss_restore_name) {
|
| LookupResult lookup(masm->isolate());
|
| object->Lookup(*name, &lookup);
|
| if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
|
| @@ -785,17 +759,8 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| holder = JSObject::cast(holder->GetPrototype());
|
| } while (holder->GetPrototype()->IsJSObject());
|
| }
|
| - // We need an extra register, push
|
| - __ push(name_reg);
|
| - Label miss_pop, done_check;
|
| CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
|
| - scratch1, scratch2, name, &miss_pop);
|
| - __ jmp(&done_check);
|
| - __ bind(&miss_pop);
|
| - __ pop(name_reg);
|
| - __ jmp(miss_label);
|
| - __ bind(&done_check);
|
| - __ pop(name_reg);
|
| + scratch1, scratch2, name, miss_restore_name);
|
| }
|
|
|
| // Stub never generated for non-global objects that require access
|
| @@ -809,7 +774,7 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| __ pop(scratch1); // Return address.
|
| __ push(receiver_reg);
|
| __ Push(transition);
|
| - __ push(rax);
|
| + __ push(value_reg);
|
| __ push(scratch1);
|
| __ TailCallExternalReference(
|
| ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
|
| @@ -843,11 +808,11 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| if (index < 0) {
|
| // Set the property straight into the object.
|
| int offset = object->map()->instance_size() + (index * kPointerSize);
|
| - __ movq(FieldOperand(receiver_reg, offset), rax);
|
| + __ movq(FieldOperand(receiver_reg, offset), value_reg);
|
|
|
| // Update the write barrier for the array address.
|
| // Pass the value being stored in the now unused name_reg.
|
| - __ movq(name_reg, rax);
|
| + __ movq(name_reg, value_reg);
|
| __ RecordWriteField(
|
| receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs);
|
| } else {
|
| @@ -855,16 +820,17 @@ void StubCompiler::GenerateStoreField(MacroAssembler* masm,
|
| int offset = index * kPointerSize + FixedArray::kHeaderSize;
|
| // Get the properties array (optimistically).
|
| __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
|
| - __ movq(FieldOperand(scratch1, offset), rax);
|
| + __ movq(FieldOperand(scratch1, offset), value_reg);
|
|
|
| // Update the write barrier for the array address.
|
| // Pass the value being stored in the now unused name_reg.
|
| - __ movq(name_reg, rax);
|
| + __ movq(name_reg, value_reg);
|
| __ RecordWriteField(
|
| scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs);
|
| }
|
|
|
| // Return the value (register rax).
|
| + ASSERT(value_reg.is(rax));
|
| __ ret(0);
|
| }
|
|
|
| @@ -908,15 +874,16 @@ static void GenerateCheckPropertyCells(MacroAssembler* masm,
|
| }
|
| }
|
|
|
| -#undef __
|
| -#define __ ACCESS_MASM((masm()))
|
|
|
| -
|
| -void StubCompiler::GenerateTailCall(Handle<Code> code) {
|
| +void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
|
| __ jmp(code, RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
| +#undef __
|
| +#define __ ACCESS_MASM((masm()))
|
| +
|
| +
|
| Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
|
| Register object_reg,
|
| Handle<JSObject> holder,
|
| @@ -1039,7 +1006,7 @@ void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
|
| if (!miss->is_unused()) {
|
| __ jmp(success);
|
| __ bind(miss);
|
| - GenerateLoadMiss(masm(), kind());
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
| }
|
| }
|
|
|
| @@ -2408,39 +2375,6 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
|
| }
|
|
|
|
|
| -Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
|
| - int index,
|
| - Handle<Map> transition,
|
| - Handle<Name> name) {
|
| - // ----------- S t a t e -------------
|
| - // -- rax : value
|
| - // -- rcx : name
|
| - // -- rdx : receiver
|
| - // -- rsp[0] : return address
|
| - // -----------------------------------
|
| - Label miss;
|
| -
|
| - // Generate store field code. Preserves receiver and name on jump to miss.
|
| - GenerateStoreField(masm(),
|
| - object,
|
| - index,
|
| - transition,
|
| - name,
|
| - rdx, rcx, rbx, rdi,
|
| - &miss);
|
| -
|
| - // Handle store cache miss.
|
| - __ bind(&miss);
|
| - Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| -
|
| - // Return the generated code.
|
| - return GetCode(transition.is_null()
|
| - ? Code::FIELD
|
| - : Code::MAP_TRANSITION, name);
|
| -}
|
| -
|
| -
|
| Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
| Handle<Name> name,
|
| Handle<JSObject> receiver,
|
| @@ -2474,11 +2408,10 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
|
|
| // Handle store cache miss.
|
| __ bind(&miss);
|
| - Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::CALLBACKS, name);
|
| + return GetICCode(kind(), Code::CALLBACKS, name);
|
| }
|
|
|
|
|
| @@ -2548,11 +2481,10 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
|
| GenerateStoreViaSetter(masm(), setter);
|
|
|
| __ bind(&miss);
|
| - Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::CALLBACKS, name);
|
| + return GetICCode(kind(), Code::CALLBACKS, name);
|
| }
|
|
|
|
|
| @@ -2584,7 +2516,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
|
| __ push(rdx); // receiver
|
| __ push(rcx); // name
|
| __ push(rax); // value
|
| - __ Push(Smi::FromInt(strict_mode_));
|
| + __ Push(Smi::FromInt(strict_mode()));
|
| __ push(rbx); // restore return address
|
|
|
| // Do tail-call to the runtime system.
|
| @@ -2594,11 +2526,10 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
|
|
|
| // Handle store cache miss.
|
| __ bind(&miss);
|
| - Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::INTERCEPTOR, name);
|
| + return GetICCode(kind(), Code::INTERCEPTOR, name);
|
| }
|
|
|
|
|
| @@ -2642,52 +2573,10 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
|
| // Handle store cache miss.
|
| __ bind(&miss);
|
| __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
|
| - Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::NORMAL, name);
|
| -}
|
| -
|
| -
|
| -Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
|
| - int index,
|
| - Handle<Map> transition,
|
| - Handle<Name> name) {
|
| - // ----------- S t a t e -------------
|
| - // -- rax : value
|
| - // -- rcx : key
|
| - // -- rdx : receiver
|
| - // -- rsp[0] : return address
|
| - // -----------------------------------
|
| - Label miss;
|
| -
|
| - Counters* counters = isolate()->counters();
|
| - __ IncrementCounter(counters->keyed_store_field(), 1);
|
| -
|
| - // Check that the name has not changed.
|
| - __ Cmp(rcx, name);
|
| - __ j(not_equal, &miss);
|
| -
|
| - // Generate store field code. Preserves receiver and name on jump to miss.
|
| - GenerateStoreField(masm(),
|
| - object,
|
| - index,
|
| - transition,
|
| - name,
|
| - rdx, rcx, rbx, rdi,
|
| - &miss);
|
| -
|
| - // Handle store cache miss.
|
| - __ bind(&miss);
|
| - __ DecrementCounter(counters->keyed_store_field(), 1);
|
| - Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ Jump(ic, RelocInfo::CODE_TARGET);
|
| -
|
| - // Return the generated code.
|
| - return GetCode(transition.is_null()
|
| - ? Code::FIELD
|
| - : Code::MAP_TRANSITION, name);
|
| + return GetICCode(kind(), Code::NORMAL, name);
|
| }
|
|
|
|
|
| @@ -2709,11 +2598,10 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
|
|
|
| __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
|
|
|
| - Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::NORMAL, factory()->empty_string());
|
| + return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
|
| }
|
|
|
|
|
| @@ -2747,11 +2635,12 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
|
| }
|
|
|
| __ bind(&miss);
|
| - Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| +
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| - return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
|
| + return GetICCode(
|
| + kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
|
| }
|
|
|
|
|
| @@ -2789,6 +2678,20 @@ Register* KeyedLoadStubCompiler::registers() {
|
| }
|
|
|
|
|
| +Register* StoreStubCompiler::registers() {
|
| + // receiver, name, value, scratch1, scratch2, scratch3.
|
| + static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
|
| + return registers;
|
| +}
|
| +
|
| +
|
| +Register* KeyedStoreStubCompiler::registers() {
|
| + // receiver, name, value, scratch1, scratch2, scratch3.
|
| + static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
|
| + return registers;
|
| +}
|
| +
|
| +
|
| void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
|
| Register name_reg,
|
| Label* miss) {
|
| @@ -2797,6 +2700,14 @@ void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
|
| }
|
|
|
|
|
| +void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
|
| + Register name_reg,
|
| + Label* miss) {
|
| + __ Cmp(name_reg, name);
|
| + __ j(not_equal, miss);
|
| +}
|
| +
|
| +
|
| #undef __
|
| #define __ ACCESS_MASM(masm)
|
|
|
| @@ -2895,7 +2806,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
|
| __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
|
| }
|
|
|
| - GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
| + TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
|
|
|
| // Return the generated code.
|
| return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
|
| @@ -2925,7 +2836,7 @@ Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
|
| }
|
|
|
| __ bind(&miss);
|
| - GenerateLoadMiss(masm(), kind());
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| InlineCacheState state =
|
| @@ -3101,9 +3012,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| - Handle<Code> slow_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_Slow();
|
| - __ jmp(slow_ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
|
|
|
| __ bind(&miss_force_generic);
|
| // ----------- S t a t e -------------
|
| @@ -3111,9 +3020,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
|
| }
|
|
|
|
|
| @@ -3311,9 +3218,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| -
|
| - Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
|
|
|
| // Miss case: call runtime.
|
| __ bind(&miss_force_generic);
|
| @@ -3324,10 +3229,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
|
| // -- rdx : receiver
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| -
|
| - Handle<Code> miss_ic =
|
| - masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| - __ jmp(miss_ic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
|
| }
|
|
|
|
|
| @@ -3396,13 +3298,10 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
|
|
| // Handle store cache miss.
|
| __ bind(&miss_force_generic);
|
| - Handle<Code> ic_force_generic =
|
| - masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| - __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
|
|
|
| __ bind(&transition_elements_kind);
|
| - Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ jmp(ic_miss, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
|
|
|
| if (is_js_array && IsGrowStoreMode(store_mode)) {
|
| // Grow the array by a single element if possible.
|
| @@ -3468,8 +3367,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| __ jmp(&finish_store);
|
|
|
| __ bind(&slow);
|
| - Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
|
| - __ jmp(ic_slow, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
|
| }
|
| }
|
|
|
| @@ -3519,16 +3417,13 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
|
|
| // Handle store cache miss, replacing the ic with the generic stub.
|
| __ bind(&miss_force_generic);
|
| - Handle<Code> ic_force_generic =
|
| - masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| - __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
|
|
|
| __ bind(&restore_key_transition_elements_kind);
|
| // Restore smi-tagging of rcx.
|
| __ Integer32ToSmi(rcx, rcx);
|
| __ bind(&transition_elements_kind);
|
| - Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
|
| - __ jmp(ic_miss, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
|
|
|
| if (is_js_array && IsGrowStoreMode(store_mode)) {
|
| // Grow the array by a single element if possible.
|
| @@ -3602,8 +3497,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
| __ jmp(&finish_store);
|
|
|
| __ bind(&slow);
|
| - Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
|
| - __ jmp(ic_slow, RelocInfo::CODE_TARGET);
|
| + TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
|
| }
|
| }
|
|
|
|
|