Index: src/ic/mips64/handler-compiler-mips64.cc |
diff --git a/src/ic/mips64/ic-compiler-mips64.cc b/src/ic/mips64/handler-compiler-mips64.cc |
similarity index 88% |
copy from src/ic/mips64/ic-compiler-mips64.cc |
copy to src/ic/mips64/handler-compiler-mips64.cc |
index 1c137ce2df78512fbb2c4dbce1f379680ef4cd0b..1b4a86711a05e1b2cfa16624ba33c90aab888dc6 100644 |
--- a/src/ic/mips64/ic-compiler-mips64.cc |
+++ b/src/ic/mips64/handler-compiler-mips64.cc |
@@ -7,7 +7,7 @@ |
#if V8_TARGET_ARCH_MIPS64 |
#include "src/ic/call-optimization.h" |
-#include "src/ic/ic-compiler.h" |
+#include "src/ic/handler-compiler.h" |
namespace v8 { |
namespace internal { |
@@ -15,6 +15,82 @@ namespace internal { |
#define __ ACCESS_MASM(masm) |
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> getter) { |
+ // ----------- S t a t e ------------- |
+ // -- a0 : receiver |
+ // -- a2 : name |
+ // -- ra : 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. |
+ __ ld(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. |
+ __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ Ret(); |
+} |
+ |
+ |
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter( |
+ MacroAssembler* masm, Handle<HeapType> type, Register receiver, |
+ Handle<JSFunction> setter) { |
+ // ----------- S t a t e ------------- |
+ // -- ra : 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. |
+ __ ld(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(v0); |
+ |
+ // Restore context register. |
+ __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ } |
+ __ Ret(); |
+} |
+ |
+ |
void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
MacroAssembler* masm, Label* miss_label, Register receiver, |
Handle<Name> name, Register scratch0, Register scratch1) { |
@@ -92,6 +168,9 @@ void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( |
} |
+// Generate code to check that a global property cell is empty. Create |
+// the property cell at compilation time if no cell exists for the |
+// property. |
void PropertyHandlerCompiler::GenerateCheckPropertyCell( |
MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, |
Register scratch, Label* miss) { |
@@ -202,6 +281,36 @@ void PropertyHandlerCompiler::GenerateFastApiCall( |
} |
+void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
+ MacroAssembler* masm) { |
+ // The return address is in ra |
+ Label slow, miss; |
+ |
+ Register key = LoadIC::NameRegister(); |
+ Register receiver = LoadIC::ReceiverRegister(); |
+ DCHECK(receiver.is(a1)); |
+ DCHECK(key.is(a2)); |
+ |
+ __ UntagAndJumpIfNotSmi(a6, key, &miss); |
+ __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
+ DCHECK(kSmiTagSize + kSmiShiftSize == 32); |
+ __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5); |
+ __ Ret(); |
+ |
+ // Slow case, key and receiver still unmodified. |
+ __ bind(&slow); |
+ __ IncrementCounter( |
+ masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3); |
+ |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
+ |
+ // Miss case, call the runtime. |
+ __ bind(&miss); |
+ |
+ TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
+} |
+ |
+ |
#undef __ |
#define __ ACCESS_MASM(masm()) |
@@ -680,54 +789,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 ------------- |
- // -- ra : 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. |
- __ ld(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(v0); |
- |
- // Restore context register. |
- __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- } |
- __ Ret(); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm()) |
- |
- |
Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
Handle<Name> name) { |
__ Push(receiver(), this->name(), value()); |
@@ -745,50 +806,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor( |
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 ------------- |
- // -- a0 : receiver |
- // -- a2 : name |
- // -- ra : 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. |
- __ ld(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. |
- __ ld(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; |
@@ -818,141 +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 { |
- __ Branch(&miss, ne, this->name(), Operand(name)); |
- } |
- } |
- |
- Label number_case; |
- Register match = scratch2(); |
- Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; |
- __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi. |
- |
- // Polymorphic keyed stores may use the map register |
- Register map_reg = scratch1(); |
- DCHECK(kind() != Code::KEYED_STORE_IC || |
- map_reg.is(KeyedStoreIC::MapRegister())); |
- |
- int receiver_count = types->length(); |
- int number_of_handled_maps = 0; |
- __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
- 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. |
- // Separate compare from branch, to provide path for above JumpIfSmi(). |
- __ Dsubu(match, map_reg, Operand(map)); |
- if (type->Is(HeapType::Number())) { |
- DCHECK(!number_case.is_unused()); |
- __ bind(&number_case); |
- } |
- __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq, match, |
- Operand(zero_reg)); |
- } |
- } |
- 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; |
- __ JumpIfSmi(receiver(), &miss); |
- |
- int receiver_count = receiver_maps->length(); |
- __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
- for (int i = 0; i < receiver_count; ++i) { |
- if (transitioned_maps->at(i).is_null()) { |
- __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(), |
- Operand(receiver_maps->at(i))); |
- } else { |
- Label next_map; |
- __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); |
- __ li(transition_map(), Operand(transitioned_maps->at(i))); |
- __ Jump(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); |
-} |
- |
- |
-#undef __ |
-#define __ ACCESS_MASM(masm) |
- |
- |
-void ElementHandlerCompiler::GenerateLoadDictionaryElement( |
- MacroAssembler* masm) { |
- // The return address is in ra |
- Label slow, miss; |
- |
- Register key = LoadIC::NameRegister(); |
- Register receiver = LoadIC::ReceiverRegister(); |
- DCHECK(receiver.is(a1)); |
- DCHECK(key.is(a2)); |
- |
- __ UntagAndJumpIfNotSmi(a6, key, &miss); |
- __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
- DCHECK(kSmiTagSize + kSmiShiftSize == 32); |
- __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5); |
- __ Ret(); |
- |
- // Slow case, key and receiver still unmodified. |
- __ bind(&slow); |
- __ IncrementCounter( |
- masm->isolate()->counters()->keyed_load_external_array_slow(), 1, a2, a3); |
- |
- 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) { |
- __ Push(StoreIC::ReceiverRegister(), StoreIC::NameRegister(), |
- StoreIC::ValueRegister()); |
- |
- __ li(a0, Operand(Smi::FromInt(strict_mode))); |
- __ Push(a0); |
- |
- // Do tail-call to runtime routine. |
- __ TailCallRuntime(Runtime::kSetProperty, 4, 1); |
-} |
- |
- |
#undef __ |
} |
} // namespace v8::internal |