Index: src/mips/ic-mips.cc |
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc |
index 68f82253d8249eb356b97a999825a9f613fa6eaf..14d1cd6827746937f45e30199f055d169ccb9e14 100644 |
--- a/src/mips/ic-mips.cc |
+++ b/src/mips/ic-mips.cc |
@@ -100,7 +100,7 @@ static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm, |
} |
-// Helper function used from LoadIC/CallIC GenerateNormal. |
+// Helper function used from LoadIC GenerateNormal. |
// |
// elements: Property dictionary. It is not clobbered if a jump to the miss |
// label is done. |
@@ -338,307 +338,8 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, |
} |
-// Defined in ic.cc. |
-Object* CallIC_Miss(Arguments args); |
- |
-// The generated code does not accept smi keys. |
-// The generated code falls through if both probes miss. |
-void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
- int argc, |
- Code::Kind kind, |
- ExtraICState extra_state) { |
- // ----------- S t a t e ------------- |
- // -- a1 : receiver |
- // -- a2 : name |
- // ----------------------------------- |
- Label number, non_number, non_string, boolean, probe, miss; |
- |
- // Probe the stub cache. |
- Code::Flags flags = Code::ComputeFlags(kind, |
- MONOMORPHIC, |
- extra_state, |
- Code::NORMAL, |
- argc); |
- masm->isolate()->stub_cache()->GenerateProbe( |
- masm, flags, a1, a2, a3, t0, t1, t2); |
- |
- // If the stub cache probing failed, the receiver might be a value. |
- // For value objects, we use the map of the prototype objects for |
- // the corresponding JSValue for the cache and that is what we need |
- // to probe. |
- // |
- // Check for number. |
- __ JumpIfSmi(a1, &number, t1); |
- __ GetObjectType(a1, a3, a3); |
- __ Branch(&non_number, ne, a3, Operand(HEAP_NUMBER_TYPE)); |
- __ bind(&number); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::NUMBER_FUNCTION_INDEX, a1); |
- __ Branch(&probe); |
- |
- // Check for string. |
- __ bind(&non_number); |
- __ Branch(&non_string, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::STRING_FUNCTION_INDEX, a1); |
- __ Branch(&probe); |
- |
- // Check for boolean. |
- __ bind(&non_string); |
- __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
- __ Branch(&boolean, eq, a1, Operand(t0)); |
- __ LoadRoot(t1, Heap::kFalseValueRootIndex); |
- __ Branch(&miss, ne, a1, Operand(t1)); |
- __ bind(&boolean); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::BOOLEAN_FUNCTION_INDEX, a1); |
- |
- // Probe the stub cache for the value object. |
- __ bind(&probe); |
- masm->isolate()->stub_cache()->GenerateProbe( |
- masm, flags, a1, a2, a3, t0, t1, t2); |
- |
- __ bind(&miss); |
-} |
- |
- |
-static void GenerateFunctionTailCall(MacroAssembler* masm, |
- int argc, |
- Label* miss, |
- Register scratch) { |
- // a1: function |
- |
- // Check that the value isn't a smi. |
- __ JumpIfSmi(a1, miss); |
- |
- // Check that the value is a JSFunction. |
- __ GetObjectType(a1, scratch, scratch); |
- __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE)); |
- |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- ra : return address |
- // ----------------------------------- |
- Label miss; |
- |
- // Get the receiver of the function from the stack into a1. |
- __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
- |
- GenerateNameDictionaryReceiverCheck(masm, a1, a0, a3, t0, &miss); |
- |
- // a0: elements |
- // Search the dictionary - put result in register a1. |
- GenerateDictionaryLoad(masm, &miss, a0, a2, a1, a3, t0); |
- |
- GenerateFunctionTailCall(masm, argc, &miss, t0); |
- |
- // Cache miss: Jump to runtime. |
- __ bind(&miss); |
-} |
- |
- |
-void CallICBase::GenerateMiss(MacroAssembler* masm, |
- int argc, |
- IC::UtilityId id, |
- ExtraICState extra_state) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- ra : return address |
- // ----------------------------------- |
- Isolate* isolate = masm->isolate(); |
- |
- if (id == IC::kCallIC_Miss) { |
- __ IncrementCounter(isolate->counters()->call_miss(), 1, a3, t0); |
- } else { |
- __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, a3, t0); |
- } |
- |
- // Get the receiver of the function from the stack. |
- __ lw(a3, MemOperand(sp, argc*kPointerSize)); |
- |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- |
- // Push the receiver and the name of the function. |
- __ Push(a3, a2); |
- |
- // Call the entry. |
- __ PrepareCEntryArgs(2); |
- __ PrepareCEntryFunction(ExternalReference(IC_Utility(id), isolate)); |
- |
- CEntryStub stub(1); |
- __ CallStub(&stub); |
- |
- // Move result to a1 and leave the internal frame. |
- __ mov(a1, v0); |
- } |
- |
- // Check if the receiver is a global object of some sort. |
- // This can happen only for regular CallIC but not KeyedCallIC. |
- if (id == IC::kCallIC_Miss) { |
- Label invoke, global; |
- __ lw(a2, MemOperand(sp, argc * kPointerSize)); |
- __ JumpIfSmi(a2, &invoke); |
- __ GetObjectType(a2, a3, a3); |
- __ Branch(&global, eq, a3, Operand(JS_GLOBAL_OBJECT_TYPE)); |
- __ Branch(&invoke, ne, a3, Operand(JS_BUILTINS_OBJECT_TYPE)); |
- |
- // Patch the receiver on the stack. |
- __ bind(&global); |
- __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
- __ sw(a2, MemOperand(sp, argc * kPointerSize)); |
- __ bind(&invoke); |
- } |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
- int argc, |
- ExtraICState extra_ic_state) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- ra : return address |
- // ----------------------------------- |
- |
- // Get the receiver of the function from the stack into a1. |
- __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
- GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); |
- GenerateMiss(masm, argc, extra_ic_state); |
-} |
- |
- |
-void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- ra : return address |
- // ----------------------------------- |
- |
- // Get the receiver of the function from the stack into a1. |
- __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
- |
- Label do_call, slow_call, slow_load, slow_reload_receiver; |
- Label check_number_dictionary, check_name, lookup_monomorphic_cache; |
- Label index_smi, index_name; |
- |
- // Check that the key is a smi. |
- __ JumpIfNotSmi(a2, &check_name); |
- __ bind(&index_smi); |
- // Now the key is known to be a smi. This place is also jumped to from below |
- // where a numeric string is converted to a smi. |
- |
- GenerateKeyedLoadReceiverCheck( |
- masm, a1, a0, a3, Map::kHasIndexedInterceptor, &slow_call); |
- |
- GenerateFastArrayLoad( |
- masm, a1, a2, t0, a3, a0, a1, &check_number_dictionary, &slow_load); |
- Counters* counters = masm->isolate()->counters(); |
- __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, a0, a3); |
- |
- __ bind(&do_call); |
- // receiver in a1 is not used after this point. |
- // a2: key |
- // a1: function |
- |
- GenerateFunctionTailCall(masm, argc, &slow_call, a0); |
- |
- __ bind(&check_number_dictionary); |
- // a2: key |
- // a3: elements map |
- // t0: elements pointer |
- // Check whether the elements is a number dictionary. |
- __ LoadRoot(at, Heap::kHashTableMapRootIndex); |
- __ Branch(&slow_load, ne, a3, Operand(at)); |
- __ sra(a0, a2, kSmiTagSize); |
- // a0: untagged index |
- __ LoadFromNumberDictionary(&slow_load, t0, a2, a1, a0, a3, t1); |
- __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3); |
- __ jmp(&do_call); |
- |
- __ bind(&slow_load); |
- // This branch is taken when calling KeyedCallIC_Miss is neither required |
- // nor beneficial. |
- __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, a0, a3); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ Push(a2, a1, a2); // Save the key and pass the receiver and the key. |
- __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
- __ pop(a2); // Restore the key. |
- } |
- __ mov(a1, v0); |
- __ jmp(&do_call); |
- |
- __ bind(&check_name); |
- GenerateKeyNameCheck(masm, a2, a0, a3, &index_name, &slow_call); |
- |
- // The key is known to be a unique name. |
- // If the receiver is a regular JS object with slow properties then do |
- // a quick inline probe of the receiver's dictionary. |
- // Otherwise do the monomorphic cache probe. |
- GenerateKeyedLoadReceiverCheck( |
- masm, a1, a0, a3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
- |
- __ lw(a0, FieldMemOperand(a1, JSObject::kPropertiesOffset)); |
- __ lw(a3, FieldMemOperand(a0, HeapObject::kMapOffset)); |
- __ LoadRoot(at, Heap::kHashTableMapRootIndex); |
- __ Branch(&lookup_monomorphic_cache, ne, a3, Operand(at)); |
- |
- GenerateDictionaryLoad(masm, &slow_load, a0, a2, a1, a3, t0); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, a0, a3); |
- __ jmp(&do_call); |
- |
- __ bind(&lookup_monomorphic_cache); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, a0, a3); |
- GenerateMonomorphicCacheProbe(masm, |
- argc, |
- Code::KEYED_CALL_IC, |
- kNoExtraICState); |
- // Fall through on miss. |
- |
- __ bind(&slow_call); |
- // This branch is taken if: |
- // - the receiver requires boxing or access check, |
- // - the key is neither smi nor a unique name, |
- // - the value loaded is not a function, |
- // - there is hope that the runtime will create a monomorphic call stub, |
- // that will get fetched next time. |
- __ IncrementCounter(counters->keyed_call_generic_slow(), 1, a0, a3); |
- GenerateMiss(masm, argc); |
- |
- __ bind(&index_name); |
- __ IndexFromHash(a3, a2); |
- // Now jump to the place where smi keys are handled. |
- __ jmp(&index_smi); |
-} |
- |
- |
-void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- ra : return address |
- // ----------------------------------- |
- |
- // Check if the name is really a name. |
- Label miss; |
- __ JumpIfSmi(a2, &miss); |
- __ IsObjectNameType(a2, a0, &miss); |
- |
- CallICBase::GenerateNormal(masm, argc); |
- __ bind(&miss); |
- GenerateMiss(masm, argc); |
-} |
- |
- |
-void LoadIC::GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode) { |
+void LoadIC::GenerateMegamorphic(MacroAssembler* masm, |
+ ExtraICState extra_state) { |
// ----------- S t a t e ------------- |
// -- a2 : name |
// -- ra : return address |
@@ -646,9 +347,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode) { |
// ----------------------------------- |
// Probe the stub cache. |
- ExtraICState extra_ic_state = LoadIC::ComputeExtraICState(mode); |
Code::Flags flags = Code::ComputeFlags( |
- Code::HANDLER, MONOMORPHIC, extra_ic_state, |
+ Code::HANDLER, MONOMORPHIC, extra_state, |
Code::NORMAL, Code::LOAD_IC); |
masm->isolate()->stub_cache()->GenerateProbe( |
masm, flags, a0, a2, a3, t0, t1, t2); |
@@ -858,32 +558,6 @@ void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { |
} |
-void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, |
- int argc) { |
- // ----------- S t a t e ------------- |
- // -- a2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- Label slow, notin; |
- // Load receiver. |
- __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
- MemOperand mapped_location = |
- GenerateMappedArgumentsLookup(masm, a1, a2, a3, t0, t1, ¬in, &slow); |
- __ lw(a1, mapped_location); |
- GenerateFunctionTailCall(masm, argc, &slow, a3); |
- __ bind(¬in); |
- // The unmapped lookup expects that the parameter map is in a3. |
- MemOperand unmapped_location = |
- GenerateUnmappedArgumentsLookup(masm, a2, a3, t0, &slow); |
- __ lw(a1, unmapped_location); |
- __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); |
- __ Branch(&slow, eq, a1, Operand(a3)); |
- GenerateFunctionTailCall(masm, argc, &slow, a3); |
- __ bind(&slow); |
- GenerateMiss(masm, argc); |
-} |
- |
- |
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
// ---------- S t a t e -------------- |
// -- ra : return address |