Index: src/ic/x64/handler-compiler-x64.cc |
diff --git a/src/ic/x64/ic-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc |
similarity index 88% |
copy from src/ic/x64/ic-compiler-x64.cc |
copy to src/ic/x64/handler-compiler-x64.cc |
index 793bd0efb5dc2fd241579cfcf447d1f8fb9429c8..0117a96978aa9eebd72470fe1b6593e2d04a1b64 100644 |
--- a/src/ic/x64/ic-compiler-x64.cc |
+++ b/src/ic/x64/handler-compiler-x64.cc |
@@ -7,14 +7,13 @@ |
#if V8_TARGET_ARCH_X64 |
#include "src/ic/call-optimization.h" |
-#include "src/ic/ic-compiler.h" |
+#include "src/ic/handler-compiler.h" |
namespace v8 { |
namespace internal { |
#define __ ACCESS_MASM(masm) |
- |
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
MacroAssembler* masm, Label* miss_label, Register receiver, |
Handle<Name> name, Register scratch0, Register scratch1) { |
@@ -199,6 +198,127 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
} |
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> setter) { |
+ // ----------- S t a t e ------------- |
+ // -- rsp[0] : return address |
+ // ----------------------------------- |
+ { |
+ FrameScope scope(masm, StackFrame::INTERNAL); |
+ |
+ // Save value register, so we can restore it later. |
+ __ Push(value()); |
+ |
+ if (!setter.is_null()) { |
+ // Call the JavaScript setter with receiver and value on the stack. |
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
+ // Swap in the global receiver. |
+ __ movp(receiver, |
+ FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
+ } |
+ __ Push(receiver); |
+ __ Push(value()); |
+ ParameterCount actual(1); |
+ ParameterCount expected(setter); |
+ __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, |
+ NullCallWrapper()); |
+ } else { |
+ // If we generate a global code snippet for deoptimization only, remember |
+ // the place to continue after deoptimization. |
+ masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); |
+ } |
+ |
+ // We have to return the passed value, not the return value of the setter. |
+ __ Pop(rax); |
+ |
+ // Restore context register. |
+ __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ ret(0); |
+} |
+ |
+ |
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> getter) { |
+ // ----------- S t a t e ------------- |
+ // -- rax : receiver |
+ // -- rcx : name |
+ // -- rsp[0] : return address |
+ // ----------------------------------- |
+ { |
+ FrameScope scope(masm, StackFrame::INTERNAL); |
+ |
+ if (!getter.is_null()) { |
+ // Call the JavaScript getter with the receiver on the stack. |
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
+ // Swap in the global receiver. |
+ __ movp(receiver, |
+ FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
+ } |
+ __ Push(receiver); |
+ ParameterCount actual(0); |
+ ParameterCount expected(getter); |
+ __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, |
+ NullCallWrapper()); |
+ } else { |
+ // If we generate a global code snippet for deoptimization only, remember |
+ // the place to continue after deoptimization. |
+ masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); |
+ } |
+ |
+ // Restore context register. |
+ __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ ret(0); |
+} |
+ |
+ |
+void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
+ MacroAssembler* masm) { |
+ // ----------- S t a t e ------------- |
+ // -- rcx : key |
+ // -- rdx : receiver |
+ // -- rsp[0] : return address |
+ // ----------------------------------- |
+ DCHECK(rdx.is(LoadIC::ReceiverRegister())); |
+ DCHECK(rcx.is(LoadIC::NameRegister())); |
+ Label slow, miss; |
+ |
+ // This stub is meant to be tail-jumped to, the receiver must already |
+ // have been verified by the caller to not be a smi. |
+ |
+ __ JumpIfNotSmi(rcx, &miss); |
+ __ SmiToInteger32(rbx, rcx); |
+ __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset)); |
+ |
+ // Check whether the elements is a number dictionary. |
+ // rdx: receiver |
+ // rcx: key |
+ // rbx: key as untagged int32 |
+ // rax: elements |
+ __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax); |
+ __ ret(0); |
+ |
+ __ bind(&slow); |
+ // ----------- S t a t e ------------- |
+ // -- rcx : key |
+ // -- rdx : receiver |
+ // -- rsp[0] : return address |
+ // ----------------------------------- |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
+ |
+ __ bind(&miss); |
+ // ----------- S t a t e ------------- |
+ // -- rcx : key |
+ // -- rdx : receiver |
+ // -- rsp[0] : return address |
+ // ----------------------------------- |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
+} |
+ |
+ |
#undef __ |
#define __ ACCESS_MASM((masm())) |
@@ -664,55 +784,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
} |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
- |
-void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
- MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
- Handle<JSFunction> setter) { |
- // ----------- S t a t e ------------- |
- // -- rsp[0] : return address |
- // ----------------------------------- |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- |
- // Save value register, so we can restore it later. |
- __ Push(value()); |
- |
- if (!setter.is_null()) { |
- // Call the JavaScript setter with receiver and value on the stack. |
- if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
- // Swap in the global receiver. |
- __ movp(receiver, |
- FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
- } |
- __ Push(receiver); |
- __ Push(value()); |
- ParameterCount actual(1); |
- ParameterCount expected(setter); |
- __ InvokeFunction(setter, expected, actual, CALL_FUNCTION, |
- NullCallWrapper()); |
- } else { |
- // If we generate a global code snippet for deoptimization only, remember |
- // the place to continue after deoptimization. |
- masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); |
- } |
- |
- // We have to return the passed value, not the return value of the setter. |
- __ Pop(rax); |
- |
- // Restore context register. |
- __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
- } |
- __ ret(0); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
Handle<Name> name) { |
__ PopReturnAddressTo(scratch1()); |
@@ -731,85 +802,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
} |
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( |
- MapHandleList* receiver_maps, CodeHandleList* handler_stubs, |
- MapHandleList* transitioned_maps) { |
- Label miss; |
- __ JumpIfSmi(receiver(), &miss, Label::kNear); |
- |
- __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); |
- int receiver_count = receiver_maps->length(); |
- for (int i = 0; i < receiver_count; ++i) { |
- // Check map and tail call if there's a match |
- __ Cmp(scratch1(), receiver_maps->at(i)); |
- if (transitioned_maps->at(i).is_null()) { |
- __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET); |
- } else { |
- Label next_map; |
- __ j(not_equal, &next_map, Label::kNear); |
- __ Move(transition_map(), transitioned_maps->at(i), |
- RelocInfo::EMBEDDED_OBJECT); |
- __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
- __ bind(&next_map); |
- } |
- } |
- |
- __ bind(&miss); |
- |
- TailCallBuiltin(masm(), MissBuiltin(kind())); |
- |
- // Return the generated code. |
- return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
-} |
- |
- |
Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
- |
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
- MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
- Handle<JSFunction> getter) { |
- // ----------- S t a t e ------------- |
- // -- rax : receiver |
- // -- rcx : name |
- // -- rsp[0] : return address |
- // ----------------------------------- |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- |
- if (!getter.is_null()) { |
- // Call the JavaScript getter with the receiver on the stack. |
- if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { |
- // Swap in the global receiver. |
- __ movp(receiver, |
- FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
- } |
- __ Push(receiver); |
- ParameterCount actual(0); |
- ParameterCount expected(getter); |
- __ InvokeFunction(getter, expected, actual, CALL_FUNCTION, |
- NullCallWrapper()); |
- } else { |
- // If we generate a global code snippet for deoptimization only, remember |
- // the place to continue after deoptimization. |
- masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); |
- } |
- |
- // Restore context register. |
- __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
- } |
- __ ret(0); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { |
Label miss; |
@@ -840,128 +835,6 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
} |
-Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types, |
- CodeHandleList* handlers, |
- Handle<Name> name, |
- Code::StubType type, |
- IcCheckType check) { |
- Label miss; |
- |
- if (check == PROPERTY && |
- (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { |
- // In case we are compiling an IC for dictionary loads and stores, just |
- // check whether the name is unique. |
- if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) { |
- __ JumpIfNotUniqueName(this->name(), &miss); |
- } else { |
- __ Cmp(this->name(), name); |
- __ j(not_equal, &miss); |
- } |
- } |
- |
- Label number_case; |
- Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; |
- __ JumpIfSmi(receiver(), smi_target); |
- |
- // Polymorphic keyed stores may use the map register |
- Register map_reg = scratch1(); |
- DCHECK(kind() != Code::KEYED_STORE_IC || |
- map_reg.is(KeyedStoreIC::MapRegister())); |
- __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); |
- int receiver_count = types->length(); |
- int number_of_handled_maps = 0; |
- for (int current = 0; current < receiver_count; ++current) { |
- Handle<HeapType> type = types->at(current); |
- Handle<Map> map = IC::TypeToMap(*type, isolate()); |
- if (!map->is_deprecated()) { |
- number_of_handled_maps++; |
- // Check map and tail call if there's a match |
- __ Cmp(map_reg, map); |
- if (type->Is(HeapType::Number())) { |
- DCHECK(!number_case.is_unused()); |
- __ bind(&number_case); |
- } |
- __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); |
- } |
- } |
- DCHECK(number_of_handled_maps > 0); |
- |
- __ bind(&miss); |
- TailCallBuiltin(masm(), MissBuiltin(kind())); |
- |
- // Return the generated code. |
- InlineCacheState state = |
- number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; |
- return GetCode(kind(), type, name, state); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
- |
-void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
- MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- rcx : key |
- // -- rdx : receiver |
- // -- rsp[0] : return address |
- // ----------------------------------- |
- DCHECK(rdx.is(LoadIC::ReceiverRegister())); |
- DCHECK(rcx.is(LoadIC::NameRegister())); |
- Label slow, miss; |
- |
- // This stub is meant to be tail-jumped to, the receiver must already |
- // have been verified by the caller to not be a smi. |
- |
- __ JumpIfNotSmi(rcx, &miss); |
- __ SmiToInteger32(rbx, rcx); |
- __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset)); |
- |
- // Check whether the elements is a number dictionary. |
- // rdx: receiver |
- // rcx: key |
- // rbx: key as untagged int32 |
- // rax: elements |
- __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax); |
- __ ret(0); |
- |
- __ bind(&slow); |
- // ----------- S t a t e ------------- |
- // -- rcx : key |
- // -- rdx : receiver |
- // -- rsp[0] : return address |
- // ----------------------------------- |
- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
- |
- __ bind(&miss); |
- // ----------- S t a t e ------------- |
- // -- rcx : key |
- // -- rdx : receiver |
- // -- rsp[0] : return address |
- // ----------------------------------- |
- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
-} |
- |
- |
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm, |
- StrictMode strict_mode) { |
- // Return address is on the stack. |
- DCHECK(!rbx.is(StoreIC::ReceiverRegister()) && |
- !rbx.is(StoreIC::NameRegister()) && !rbx.is(StoreIC::ValueRegister())); |
- |
- __ PopReturnAddressTo(rbx); |
- __ Push(StoreIC::ReceiverRegister()); |
- __ Push(StoreIC::NameRegister()); |
- __ Push(StoreIC::ValueRegister()); |
- __ Push(Smi::FromInt(strict_mode)); |
- __ PushReturnAddressFrom(rbx); |
- |
- // Do tail-call to runtime routine. |
- __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
-} |
- |
- |
#undef __ |
} |
} // namespace v8::internal |