| 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);
|
|
|