Index: src/arm/ic-arm.cc |
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc |
index 5ccbd734358a240fc9e6b3b88977032cd243d4ea..d324a8c6b32c960b40e94d3ab037fe5f53b97941 100644 |
--- a/src/arm/ic-arm.cc |
+++ b/src/arm/ic-arm.cc |
@@ -104,7 +104,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. |
@@ -333,313 +333,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 ------------- |
- // -- r1 : receiver |
- // -- r2 : 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, r1, r2, r3, r4, r5, r6); |
- |
- // 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(r1, &number); |
- __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); |
- __ b(ne, &non_number); |
- __ bind(&number); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::NUMBER_FUNCTION_INDEX, r1); |
- __ b(&probe); |
- |
- // Check for string. |
- __ bind(&non_number); |
- __ cmp(r3, Operand(FIRST_NONSTRING_TYPE)); |
- __ b(hs, &non_string); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::STRING_FUNCTION_INDEX, r1); |
- __ b(&probe); |
- |
- // Check for boolean. |
- __ bind(&non_string); |
- __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
- __ cmp(r1, ip); |
- __ b(eq, &boolean); |
- __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
- __ cmp(r1, ip); |
- __ b(ne, &miss); |
- __ bind(&boolean); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::BOOLEAN_FUNCTION_INDEX, r1); |
- |
- // Probe the stub cache for the value object. |
- __ bind(&probe); |
- masm->isolate()->stub_cache()->GenerateProbe( |
- masm, flags, r1, r2, r3, r4, r5, r6); |
- |
- __ bind(&miss); |
-} |
- |
- |
-static void GenerateFunctionTailCall(MacroAssembler* masm, |
- int argc, |
- Label* miss, |
- Register scratch) { |
- // r1: function |
- |
- // Check that the value isn't a smi. |
- __ JumpIfSmi(r1, miss); |
- |
- // Check that the value is a JSFunction. |
- __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE); |
- __ b(ne, miss); |
- |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { |
- // ----------- S t a t e ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- Label miss; |
- |
- // Get the receiver of the function from the stack into r1. |
- __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
- |
- GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss); |
- |
- // r0: elements |
- // Search the dictionary - put result in register r1. |
- GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); |
- |
- GenerateFunctionTailCall(masm, argc, &miss, r4); |
- |
- __ bind(&miss); |
-} |
- |
- |
-void CallICBase::GenerateMiss(MacroAssembler* masm, |
- int argc, |
- IC::UtilityId id, |
- ExtraICState extra_state) { |
- // ----------- S t a t e ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- Isolate* isolate = masm->isolate(); |
- |
- if (id == IC::kCallIC_Miss) { |
- __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); |
- } else { |
- __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); |
- } |
- |
- // Get the receiver of the function from the stack. |
- __ ldr(r3, MemOperand(sp, argc * kPointerSize)); |
- |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- |
- // Push the receiver and the name of the function. |
- __ Push(r3, r2); |
- |
- // Call the entry. |
- __ mov(r0, Operand(2)); |
- __ mov(r1, Operand(ExternalReference(IC_Utility(id), isolate))); |
- |
- CEntryStub stub(1); |
- __ CallStub(&stub); |
- |
- // Move result to r1 and leave the internal frame. |
- __ mov(r1, Operand(r0)); |
- } |
- |
- // 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; |
- __ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver |
- __ JumpIfSmi(r2, &invoke); |
- __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE); |
- __ b(eq, &global); |
- __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); |
- __ b(ne, &invoke); |
- |
- // Patch the receiver on the stack. |
- __ bind(&global); |
- __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
- __ str(r2, MemOperand(sp, argc * kPointerSize)); |
- __ bind(&invoke); |
- } |
- |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
- int argc, |
- ExtraICState extra_ic_state) { |
- // ----------- S t a t e ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Get the receiver of the function from the stack into r1. |
- __ ldr(r1, 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 ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Get the receiver of the function from the stack into r1. |
- __ ldr(r1, 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(r2, &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, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); |
- |
- GenerateFastArrayLoad( |
- masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); |
- Counters* counters = masm->isolate()->counters(); |
- __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, r0, r3); |
- |
- __ bind(&do_call); |
- // receiver in r1 is not used after this point. |
- // r2: key |
- // r1: function |
- GenerateFunctionTailCall(masm, argc, &slow_call, r0); |
- |
- __ bind(&check_number_dictionary); |
- // r2: key |
- // r3: elements map |
- // r4: elements |
- // Check whether the elements is a number dictionary. |
- __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
- __ cmp(r3, ip); |
- __ b(ne, &slow_load); |
- __ SmiUntag(r0, r2); |
- // r0: untagged index |
- __ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5); |
- __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3); |
- __ 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, r0, r3); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ Push(r2, r1); // save the key and the receiver |
- __ push(r2); // pass the receiver and the key |
- __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
- __ pop(r2); // restore the key |
- } |
- __ mov(r1, r0); |
- __ jmp(&do_call); |
- |
- __ bind(&check_name); |
- GenerateKeyNameCheck(masm, r2, r0, r3, &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, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
- |
- __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
- __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); |
- __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
- __ cmp(r3, ip); |
- __ b(ne, &lookup_monomorphic_cache); |
- |
- GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3); |
- __ jmp(&do_call); |
- |
- __ bind(&lookup_monomorphic_cache); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3); |
- 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, r0, r3); |
- GenerateMiss(masm, argc); |
- |
- __ bind(&index_name); |
- __ IndexFromHash(r3, r2); |
- // 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 ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Check if the name is really a name. |
- Label miss; |
- __ JumpIfSmi(r2, &miss); |
- __ IsObjectNameType(r2, r0, &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 ------------- |
// -- r2 : name |
// -- lr : return address |
@@ -647,9 +342,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, r0, r2, r3, r4, r5, r6); |
@@ -853,33 +547,6 @@ void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { |
} |
-void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, |
- int argc) { |
- // ----------- S t a t e ------------- |
- // -- r2 : name |
- // -- lr : return address |
- // ----------------------------------- |
- Label slow, notin; |
- // Load receiver. |
- __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
- MemOperand mapped_location = |
- GenerateMappedArgumentsLookup(masm, r1, r2, r3, r4, r5, ¬in, &slow); |
- __ ldr(r1, mapped_location); |
- GenerateFunctionTailCall(masm, argc, &slow, r3); |
- __ bind(¬in); |
- // The unmapped lookup expects that the parameter map is in r3. |
- MemOperand unmapped_location = |
- GenerateUnmappedArgumentsLookup(masm, r2, r3, r4, &slow); |
- __ ldr(r1, unmapped_location); |
- __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); |
- __ cmp(r1, r3); |
- __ b(eq, &slow); |
- GenerateFunctionTailCall(masm, argc, &slow, r3); |
- __ bind(&slow); |
- GenerateMiss(masm, argc); |
-} |
- |
- |
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
// ---------- S t a t e -------------- |
// -- lr : return address |