Index: src/x64/ic-x64.cc |
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc |
index b307e693e33978b6babe21cd585812116f5ea9fe..c76eca04d8ce80b7518a990692c4afbebca91b41 100644 |
--- a/src/x64/ic-x64.cc |
+++ b/src/x64/ic-x64.cc |
@@ -828,339 +828,6 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
} |
-// 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 ------------- |
- // rcx : function name |
- // rdx : receiver |
- // ----------------------------------- |
- 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, rdx, rcx, rbx, rax); |
- |
- // 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(rdx, &number); |
- __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx); |
- __ j(not_equal, &non_number); |
- __ bind(&number); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::NUMBER_FUNCTION_INDEX, rdx); |
- __ jmp(&probe); |
- |
- // Check for string. |
- __ bind(&non_number); |
- __ CmpInstanceType(rbx, FIRST_NONSTRING_TYPE); |
- __ j(above_equal, &non_string); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::STRING_FUNCTION_INDEX, rdx); |
- __ jmp(&probe); |
- |
- // Check for boolean. |
- __ bind(&non_string); |
- __ CompareRoot(rdx, Heap::kTrueValueRootIndex); |
- __ j(equal, &boolean); |
- __ CompareRoot(rdx, Heap::kFalseValueRootIndex); |
- __ j(not_equal, &miss); |
- __ bind(&boolean); |
- StubCompiler::GenerateLoadGlobalFunctionPrototype( |
- masm, Context::BOOLEAN_FUNCTION_INDEX, rdx); |
- |
- // Probe the stub cache for the value object. |
- __ bind(&probe); |
- masm->isolate()->stub_cache()->GenerateProbe( |
- masm, flags, rdx, rcx, rbx, no_reg); |
- |
- __ bind(&miss); |
-} |
- |
- |
-static void GenerateFunctionTailCall(MacroAssembler* masm, |
- int argc, |
- Label* miss) { |
- // ----------- S t a t e ------------- |
- // rcx : function name |
- // rdi : function |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- __ JumpIfSmi(rdi, miss); |
- // Check that the value is a JavaScript function. |
- __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rdx); |
- __ j(not_equal, miss); |
- |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-// The generated code falls through if the call should be handled by runtime. |
-void CallICBase::GenerateNormal(MacroAssembler* masm, int argc) { |
- // ----------- S t a t e ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- Label miss; |
- |
- StackArgumentsAccessor args(rsp, argc); |
- __ movp(rdx, args.GetReceiverOperand()); |
- |
- GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); |
- |
- // rax: elements |
- // Search the dictionary placing the result in rdi. |
- GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi); |
- |
- GenerateFunctionTailCall(masm, argc, &miss); |
- |
- __ bind(&miss); |
-} |
- |
- |
-void CallICBase::GenerateMiss(MacroAssembler* masm, |
- int argc, |
- IC::UtilityId id, |
- ExtraICState extra_state) { |
- // ----------- S t a t e ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- |
- Counters* counters = masm->isolate()->counters(); |
- if (id == IC::kCallIC_Miss) { |
- __ IncrementCounter(counters->call_miss(), 1); |
- } else { |
- __ IncrementCounter(counters->keyed_call_miss(), 1); |
- } |
- |
- StackArgumentsAccessor args(rsp, argc); |
- __ movp(rdx, args.GetReceiverOperand()); |
- |
- // Enter an internal frame. |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- |
- // Push the receiver and the name of the function. |
- __ push(rdx); |
- __ push(rcx); |
- |
- // Call the entry. |
- CEntryStub stub(1); |
- __ Set(rax, 2); |
- __ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate())); |
- __ CallStub(&stub); |
- |
- // Move result to rdi and exit the internal frame. |
- __ movp(rdi, rax); |
- } |
- |
- // 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; |
- __ movp(rdx, args.GetReceiverOperand()); |
- __ JumpIfSmi(rdx, &invoke); |
- __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx); |
- __ j(equal, &global); |
- __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE); |
- __ j(not_equal, &invoke); |
- |
- // Patch the receiver on the stack. |
- __ bind(&global); |
- __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
- __ movp(args.GetReceiverOperand(), rdx); |
- __ bind(&invoke); |
- } |
- |
- // Invoke the function. |
- ParameterCount actual(argc); |
- __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); |
-} |
- |
- |
-void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
- int argc, |
- ExtraICState extra_ic_state) { |
- // ----------- S t a t e ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- |
- StackArgumentsAccessor args(rsp, argc); |
- __ movp(rdx, args.GetReceiverOperand()); |
- 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 ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- |
- StackArgumentsAccessor args(rsp, argc); |
- __ movp(rdx, args.GetReceiverOperand()); |
- |
- Label do_call, slow_call, slow_load; |
- Label check_number_dictionary, check_name, lookup_monomorphic_cache; |
- Label index_smi, index_name; |
- |
- // Check that the key is a smi. |
- __ JumpIfNotSmi(rcx, &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, rdx, rax, Map::kHasIndexedInterceptor, &slow_call); |
- |
- GenerateFastArrayLoad( |
- masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load); |
- Counters* counters = masm->isolate()->counters(); |
- __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1); |
- |
- __ bind(&do_call); |
- // receiver in rdx is not used after this point. |
- // rcx: key |
- // rdi: function |
- GenerateFunctionTailCall(masm, argc, &slow_call); |
- |
- __ bind(&check_number_dictionary); |
- // rax: elements |
- // rcx: smi key |
- // Check whether the elements is a number dictionary. |
- __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
- Heap::kHashTableMapRootIndex); |
- __ j(not_equal, &slow_load); |
- __ SmiToInteger32(rbx, rcx); |
- // ebx: untagged index |
- __ LoadFromNumberDictionary(&slow_load, rax, rcx, rbx, r9, rdi, rdi); |
- __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1); |
- __ 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); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ push(rcx); // save the key |
- __ push(rdx); // pass the receiver |
- __ push(rcx); // pass the key |
- __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
- __ pop(rcx); // restore the key |
- } |
- __ movp(rdi, rax); |
- __ jmp(&do_call); |
- |
- __ bind(&check_name); |
- GenerateKeyNameCheck(masm, rcx, rax, rbx, &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, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
- |
- __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); |
- __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
- Heap::kHashTableMapRootIndex); |
- __ j(not_equal, &lookup_monomorphic_cache); |
- |
- GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); |
- __ jmp(&do_call); |
- |
- __ bind(&lookup_monomorphic_cache); |
- __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); |
- 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); |
- GenerateMiss(masm, argc); |
- |
- __ bind(&index_name); |
- __ IndexFromHash(rbx, rcx); |
- // 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 ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- |
- // Check if the name is really a name. |
- Label miss; |
- __ JumpIfSmi(rcx, &miss); |
- Condition cond = masm->IsObjectNameType(rcx, rax, rax); |
- __ j(NegateCondition(cond), &miss); |
- CallICBase::GenerateNormal(masm, argc); |
- __ bind(&miss); |
- GenerateMiss(masm, argc); |
-} |
- |
- |
static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, |
Register object, |
Register key, |
@@ -1306,38 +973,8 @@ void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { |
} |
-void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, |
- int argc) { |
- // ----------- S t a t e ------------- |
- // rcx : function name |
- // rsp[0] : return address |
- // rsp[8] : argument argc |
- // rsp[16] : argument argc - 1 |
- // ... |
- // rsp[argc * 8] : argument 1 |
- // rsp[(argc + 1) * 8] : argument 0 = receiver |
- // ----------------------------------- |
- Label slow, notin; |
- StackArgumentsAccessor args(rsp, argc); |
- __ movp(rdx, args.GetReceiverOperand()); |
- Operand mapped_location = GenerateMappedArgumentsLookup( |
- masm, rdx, rcx, rbx, rax, r8, ¬in, &slow); |
- __ movp(rdi, mapped_location); |
- GenerateFunctionTailCall(masm, argc, &slow); |
- __ bind(¬in); |
- // The unmapped lookup expects that the parameter map is in rbx. |
- Operand unmapped_location = |
- GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rax, &slow); |
- __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); |
- __ j(equal, &slow); |
- __ movp(rdi, unmapped_location); |
- GenerateFunctionTailCall(masm, argc, &slow); |
- __ bind(&slow); |
- GenerateMiss(masm, argc); |
-} |
- |
- |
-void LoadIC::GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode) { |
+void LoadIC::GenerateMegamorphic(MacroAssembler* masm, |
+ ExtraICState extra_state) { |
// ----------- S t a t e ------------- |
// -- rax : receiver |
// -- rcx : name |
@@ -1345,9 +982,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, rax, rcx, rbx, rdx); |