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); |
} |
} |