Index: src/ic/arm64/handler-compiler-arm64.cc |
diff --git a/src/ic/arm64/ic-compiler-arm64.cc b/src/ic/arm64/handler-compiler-arm64.cc |
similarity index 88% |
copy from src/ic/arm64/ic-compiler-arm64.cc |
copy to src/ic/arm64/handler-compiler-arm64.cc |
index 3e7f8f50a0a39c8d00819b70d103f7d1a7605aa1..e0678db6870952d37c2f8a4328e4c264f8b7ef42 100644 |
--- a/src/ic/arm64/ic-compiler-arm64.cc |
+++ b/src/ic/arm64/handler-compiler-arm64.cc |
@@ -7,7 +7,7 @@ |
#if V8_TARGET_ARCH_ARM64 |
#include "src/ic/call-optimization.h" |
-#include "src/ic/ic-compiler.h" |
+#include "src/ic/handler-compiler.h" |
namespace v8 { |
namespace internal { |
@@ -206,10 +206,157 @@ void PropertyHandlerCompiler::GenerateFastApiCall( |
} |
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> setter) { |
+ // ----------- S t a t e ------------- |
+ // -- lr : return address |
+ // ----------------------------------- |
+ Label miss; |
+ |
+ { |
+ 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. |
+ __ Ldr(receiver, |
+ FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
+ } |
+ __ Push(receiver, 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(x0); |
+ |
+ // Restore context register. |
+ __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ Ret(); |
+} |
+ |
+ |
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> getter) { |
+ { |
+ 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. |
+ __ Ldr(receiver, |
+ FieldMemOperand(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. |
+ __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ Ret(); |
+} |
+ |
+ |
+void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
+ MacroAssembler* masm) { |
+ // The return address is in lr. |
+ Label slow, miss; |
+ |
+ Register result = x0; |
+ Register key = LoadIC::NameRegister(); |
+ Register receiver = LoadIC::ReceiverRegister(); |
+ DCHECK(receiver.is(x1)); |
+ DCHECK(key.is(x2)); |
+ |
+ __ JumpIfNotSmi(key, &miss); |
+ __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
+ __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6); |
+ __ Ret(); |
+ |
+ __ Bind(&slow); |
+ __ IncrementCounter( |
+ masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3); |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
+ |
+ // Miss case, call the runtime. |
+ __ Bind(&miss); |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
+} |
+ |
+ |
#undef __ |
#define __ ACCESS_MASM(masm()) |
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
+ Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { |
+ Label miss; |
+ FrontendHeader(receiver(), name, &miss); |
+ |
+ // Get the value from the cell. |
+ Register result = StoreIC::ValueRegister(); |
+ __ Mov(result, Operand(cell)); |
+ __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset)); |
+ |
+ // Check for deleted property if property can actually be deleted. |
+ if (is_configurable) { |
+ __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss); |
+ } |
+ |
+ Counters* counters = isolate()->counters(); |
+ __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3); |
+ __ Ret(); |
+ |
+ FrontendFooter(name, &miss); |
+ |
+ // Return the generated code. |
+ return GetCode(kind(), Code::NORMAL, name); |
+} |
+ |
+ |
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
+ Handle<Name> name) { |
+ Label miss; |
+ |
+ ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor"); |
+ |
+ __ Push(receiver(), this->name(), value()); |
+ |
+ // Do tail-call to the runtime system. |
+ ExternalReference store_ic_property = ExternalReference( |
+ IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); |
+ __ TailCallExternalReference(store_ic_property, 3, 1); |
+ |
+ // Return the generated code. |
+ return GetCode(kind(), Code::FAST, name); |
+} |
+ |
+ |
+Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } |
+ |
+ |
void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, |
Handle<Name> name) { |
if (!label->is_unused()) { |
@@ -691,276 +838,7 @@ 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 ------------- |
- // -- lr : return address |
- // ----------------------------------- |
- Label miss; |
- |
- { |
- 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. |
- __ Ldr(receiver, |
- FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); |
- } |
- __ Push(receiver, 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(x0); |
- |
- // Restore context register. |
- __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- } |
- __ Ret(); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
-Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
- Handle<Name> name) { |
- Label miss; |
- |
- ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreInterceptor"); |
- |
- __ Push(receiver(), this->name(), value()); |
- |
- // Do tail-call to the runtime system. |
- ExternalReference store_ic_property = ExternalReference( |
- IC_Utility(IC::kStorePropertyWithInterceptor), isolate()); |
- __ TailCallExternalReference(store_ic_property, 3, 1); |
- |
- // Return the generated code. |
- return GetCode(kind(), Code::FAST, name); |
-} |
- |
- |
-Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); } |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
-void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
- MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
- Handle<JSFunction> getter) { |
- { |
- 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. |
- __ Ldr(receiver, |
- FieldMemOperand(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. |
- __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- } |
- __ Ret(); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
-Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
- Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { |
- Label miss; |
- FrontendHeader(receiver(), name, &miss); |
- |
- // Get the value from the cell. |
- Register result = StoreIC::ValueRegister(); |
- __ Mov(result, Operand(cell)); |
- __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset)); |
- |
- // Check for deleted property if property can actually be deleted. |
- if (is_configurable) { |
- __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss); |
- } |
- |
- Counters* counters = isolate()->counters(); |
- __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3); |
- __ Ret(); |
- |
- FrontendFooter(name, &miss); |
- |
- // Return the generated code. |
- return GetCode(kind(), Code::NORMAL, name); |
-} |
- |
- |
-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 { |
- __ CompareAndBranch(this->name(), Operand(name), ne, &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())); |
- __ Ldr(map_reg, FieldMemOperand(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++; |
- Label try_next; |
- __ Cmp(map_reg, Operand(map)); |
- __ B(ne, &try_next); |
- if (type->Is(HeapType::Number())) { |
- DCHECK(!number_case.is_unused()); |
- __ Bind(&number_case); |
- } |
- __ Jump(handlers->at(current), RelocInfo::CODE_TARGET); |
- __ Bind(&try_next); |
- } |
- } |
- 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); |
-} |
- |
- |
-Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( |
- MapHandleList* receiver_maps, CodeHandleList* handler_stubs, |
- MapHandleList* transitioned_maps) { |
- Label miss; |
- |
- ASM_LOCATION("PropertyICCompiler::CompileStorePolymorphic"); |
- |
- __ JumpIfSmi(receiver(), &miss); |
- |
- int receiver_count = receiver_maps->length(); |
- __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
- for (int i = 0; i < receiver_count; i++) { |
- __ Cmp(scratch1(), Operand(receiver_maps->at(i))); |
- |
- Label skip; |
- __ B(&skip, ne); |
- if (!transitioned_maps->at(i).is_null()) { |
- // This argument is used by the handler stub. For example, see |
- // ElementsTransitionGenerator::GenerateMapChangeElementsTransition. |
- __ Mov(transition_map(), Operand(transitioned_maps->at(i))); |
- } |
- __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
- __ Bind(&skip); |
- } |
- |
- __ Bind(&miss); |
- TailCallBuiltin(masm(), MissBuiltin(kind())); |
- |
- return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
-void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
- MacroAssembler* masm) { |
- // The return address is in lr. |
- Label slow, miss; |
- |
- Register result = x0; |
- Register key = LoadIC::NameRegister(); |
- Register receiver = LoadIC::ReceiverRegister(); |
- DCHECK(receiver.is(x1)); |
- DCHECK(key.is(x2)); |
- |
- __ JumpIfNotSmi(key, &miss); |
- __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
- __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6); |
- __ Ret(); |
- |
- __ Bind(&slow); |
- __ IncrementCounter( |
- masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3); |
- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
- |
- // Miss case, call the runtime. |
- __ Bind(&miss); |
- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
-} |
- |
- |
-void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm, |
- StrictMode strict_mode) { |
- ASM_LOCATION("PropertyICCompiler::GenerateRuntimeSetProperty"); |
- |
- __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(), |
- StoreIC::ValueRegister()); |
- |
- __ Mov(x10, Smi::FromInt(strict_mode)); |
- __ Push(x10); |
- |
- // Do tail-call to runtime routine. |
- __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
-} |
- |
- |
-#undef __ |
} |
} // namespace v8::internal |
-#endif // V8_TARGET_ARCH_ARM64 |
+#endif // V8_TARGET_ARCH_IA32 |