Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 96573002: Revert r18131 and r18139 "Clean up in the CallStubCompiler". (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 thunk_address, 630 thunk_address,
631 callback_arg, 631 callback_arg,
632 argc + kFastApiCallArguments + 1, 632 argc + kFastApiCallArguments + 1,
633 return_value_operand, 633 return_value_operand,
634 restore_context ? &context_restore_operand : NULL); 634 restore_context ? &context_restore_operand : NULL);
635 } 635 }
636 636
637 637
638 class CallInterceptorCompiler BASE_EMBEDDED { 638 class CallInterceptorCompiler BASE_EMBEDDED {
639 public: 639 public:
640 CallInterceptorCompiler(CallStubCompiler* stub_compiler, 640 CallInterceptorCompiler(StubCompiler* stub_compiler,
641 const ParameterCount& arguments, 641 const ParameterCount& arguments,
642 Register name, 642 Register name,
643 ExtraICState extra_ic_state) 643 ExtraICState extra_ic_state)
644 : stub_compiler_(stub_compiler), 644 : stub_compiler_(stub_compiler),
645 arguments_(arguments), 645 arguments_(arguments),
646 name_(name), 646 name_(name),
647 extra_ic_state_(extra_ic_state) {} 647 extra_ic_state_(extra_ic_state) {}
648 648
649 void Compile(MacroAssembler* masm, 649 void Compile(MacroAssembler* masm,
650 Handle<JSObject> object, 650 Handle<JSObject> object,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 // for API (object which is instanceof for the signature). It's 741 // for API (object which is instanceof for the signature). It's
742 // safe to omit it here, as if present, it should be fetched 742 // safe to omit it here, as if present, it should be fetched
743 // by the previous CheckPrototypes. 743 // by the previous CheckPrototypes.
744 ASSERT(depth2 == kInvalidProtoDepth); 744 ASSERT(depth2 == kInvalidProtoDepth);
745 } 745 }
746 746
747 // Invoke function. 747 // Invoke function.
748 if (can_do_fast_api_call) { 748 if (can_do_fast_api_call) {
749 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 749 GenerateFastApiCall(masm, optimization, arguments_.immediate());
750 } else { 750 } else {
751 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
752 ? CALL_AS_FUNCTION
753 : CALL_AS_METHOD;
751 Handle<JSFunction> fun = optimization.constant_function(); 754 Handle<JSFunction> fun = optimization.constant_function();
752 stub_compiler_->GenerateJumpFunction(object, fun); 755 ParameterCount expected(fun);
756 __ InvokeFunction(fun, expected, arguments_,
757 JUMP_FUNCTION, NullCallWrapper(), call_kind);
753 } 758 }
754 759
755 // Deferred code for fast API call case---clean preallocated space. 760 // Deferred code for fast API call case---clean preallocated space.
756 if (can_do_fast_api_call) { 761 if (can_do_fast_api_call) {
757 __ bind(&miss_cleanup); 762 __ bind(&miss_cleanup);
758 FreeSpaceForFastApiCall(masm, scratch1); 763 FreeSpaceForFastApiCall(masm, scratch1);
759 __ jmp(miss_label); 764 __ jmp(miss_label);
760 } 765 }
761 766
762 // Invoke a regular function. 767 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 815
811 __ pop(name_); // Restore the name. 816 __ pop(name_); // Restore the name.
812 __ pop(receiver); // Restore the holder. 817 __ pop(receiver); // Restore the holder.
813 // Leave the internal frame. 818 // Leave the internal frame.
814 } 819 }
815 820
816 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
817 __ j(not_equal, interceptor_succeeded); 822 __ j(not_equal, interceptor_succeeded);
818 } 823 }
819 824
820 CallStubCompiler* stub_compiler_; 825 StubCompiler* stub_compiler_;
821 const ParameterCount& arguments_; 826 const ParameterCount& arguments_;
822 Register name_; 827 Register name_;
823 ExtraICState extra_ic_state_; 828 ExtraICState extra_ic_state_;
824 }; 829 };
825 830
826 831
827 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 832 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
828 Label* label, 833 Label* label,
829 Handle<Name> name) { 834 Handle<Name> name) {
830 if (!label->is_unused()) { 835 if (!label->is_unused()) {
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 1530
1526 1531
1527 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1532 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1528 if (kind_ == Code::KEYED_CALL_IC) { 1533 if (kind_ == Code::KEYED_CALL_IC) {
1529 __ Cmp(rcx, name); 1534 __ Cmp(rcx, name);
1530 __ j(not_equal, miss); 1535 __ j(not_equal, miss);
1531 } 1536 }
1532 } 1537 }
1533 1538
1534 1539
1535 void CallStubCompiler::GenerateFunctionCheck(Register function,
1536 Register scratch,
1537 Label* miss) {
1538 __ JumpIfSmi(function, miss);
1539 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1540 __ j(not_equal, miss);
1541 }
1542
1543
1544 void CallStubCompiler::GenerateLoadFunctionFromCell( 1540 void CallStubCompiler::GenerateLoadFunctionFromCell(
1545 Handle<Cell> cell, 1541 Handle<Cell> cell,
1546 Handle<JSFunction> function, 1542 Handle<JSFunction> function,
1547 Label* miss) { 1543 Label* miss) {
1548 // Get the value from the cell. 1544 // Get the value from the cell.
1549 __ Move(rdi, cell); 1545 __ Move(rdi, cell);
1550 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1546 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
1551 1547
1552 // Check that the cell contains the same function. 1548 // Check that the cell contains the same function.
1553 if (heap()->InNewSpace(*function)) { 1549 if (heap()->InNewSpace(*function)) {
1554 // We can't embed a pointer to a function in new space so we have 1550 // We can't embed a pointer to a function in new space so we have
1555 // to verify that the shared function info is unchanged. This has 1551 // to verify that the shared function info is unchanged. This has
1556 // the nice side effect that multiple closures based on the same 1552 // the nice side effect that multiple closures based on the same
1557 // function can all use this call IC. Before we load through the 1553 // function can all use this call IC. Before we load through the
1558 // function, we have to verify that it still is a function. 1554 // function, we have to verify that it still is a function.
1559 GenerateFunctionCheck(rdi, rax, miss); 1555 __ JumpIfSmi(rdi, miss);
1556 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
1557 __ j(not_equal, miss);
1560 1558
1561 // Check the shared function info. Make sure it hasn't changed. 1559 // Check the shared function info. Make sure it hasn't changed.
1562 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1560 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1563 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1561 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1564 } else { 1562 } else {
1565 __ Cmp(rdi, function); 1563 __ Cmp(rdi, function);
1566 } 1564 }
1567 __ j(not_equal, miss); 1565 __ j(not_equal, miss);
1568 } 1566 }
1569 1567
(...skipping 11 matching lines...) Expand all
1581 Handle<JSObject> holder, 1579 Handle<JSObject> holder,
1582 PropertyIndex index, 1580 PropertyIndex index,
1583 Handle<Name> name) { 1581 Handle<Name> name) {
1584 Label miss; 1582 Label miss;
1585 1583
1586 Register reg = HandlerFrontendHeader( 1584 Register reg = HandlerFrontendHeader(
1587 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1585 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1588 1586
1589 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1587 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1590 index.translate(holder), Representation::Tagged()); 1588 index.translate(holder), Representation::Tagged());
1591 GenerateJumpFunction(object, rdi, &miss); 1589
1590 // Check that the function really is a function.
1591 __ JumpIfSmi(rdi, &miss);
1592 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1593 __ j(not_equal, &miss);
1594
1595 PatchGlobalProxy(object);
1596
1597 // Invoke the function.
1598 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1599 ? CALL_AS_FUNCTION
1600 : CALL_AS_METHOD;
1601 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1602 NullCallWrapper(), call_kind);
1592 1603
1593 HandlerFrontendFooter(&miss); 1604 HandlerFrontendFooter(&miss);
1594 1605
1595 // Return the generated code. 1606 // Return the generated code.
1596 return GetCode(Code::FAST, name); 1607 return GetCode(Code::FAST, name);
1597 } 1608 }
1598 1609
1599 1610
1600 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1601 Handle<Object> object, 1612 Handle<Object> object,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 2007
1997 if (index_out_of_range.is_linked()) { 2008 if (index_out_of_range.is_linked()) {
1998 __ bind(&index_out_of_range); 2009 __ bind(&index_out_of_range);
1999 __ LoadRoot(rax, Heap::kNanValueRootIndex); 2010 __ LoadRoot(rax, Heap::kNanValueRootIndex);
2000 __ ret((argc + 1) * kPointerSize); 2011 __ ret((argc + 1) * kPointerSize);
2001 } 2012 }
2002 2013
2003 __ bind(&miss); 2014 __ bind(&miss);
2004 // Restore function name in rcx. 2015 // Restore function name in rcx.
2005 __ Move(rcx, name); 2016 __ Move(rcx, name);
2006 HandlerFrontendFooter(&name_miss); 2017 __ bind(&name_miss);
2018 GenerateMissBranch();
2007 2019
2008 // Return the generated code. 2020 // Return the generated code.
2009 return GetCode(type, name); 2021 return GetCode(type, name);
2010 } 2022 }
2011 2023
2012 2024
2013 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2014 Handle<Object> object, 2026 Handle<Object> object,
2015 Handle<JSObject> holder, 2027 Handle<JSObject> holder,
2016 Handle<Cell> cell, 2028 Handle<Cell> cell,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 generator.GenerateSlow(masm(), call_helper); 2073 generator.GenerateSlow(masm(), call_helper);
2062 2074
2063 if (index_out_of_range.is_linked()) { 2075 if (index_out_of_range.is_linked()) {
2064 __ bind(&index_out_of_range); 2076 __ bind(&index_out_of_range);
2065 __ LoadRoot(rax, Heap::kempty_stringRootIndex); 2077 __ LoadRoot(rax, Heap::kempty_stringRootIndex);
2066 __ ret((argc + 1) * kPointerSize); 2078 __ ret((argc + 1) * kPointerSize);
2067 } 2079 }
2068 __ bind(&miss); 2080 __ bind(&miss);
2069 // Restore function name in rcx. 2081 // Restore function name in rcx.
2070 __ Move(rcx, name); 2082 __ Move(rcx, name);
2071 HandlerFrontendFooter(&name_miss); 2083 __ bind(&name_miss);
2084 GenerateMissBranch();
2072 2085
2073 // Return the generated code. 2086 // Return the generated code.
2074 return GetCode(type, name); 2087 return GetCode(type, name);
2075 } 2088 }
2076 2089
2077 2090
2078 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2091 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2079 Handle<Object> object, 2092 Handle<Object> object,
2080 Handle<JSObject> holder, 2093 Handle<JSObject> holder,
2081 Handle<Cell> cell, 2094 Handle<Cell> cell,
(...skipping 25 matching lines...) Expand all
2107 // Convert the smi code to uint16. 2120 // Convert the smi code to uint16.
2108 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2121 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2109 2122
2110 StringCharFromCodeGenerator generator(code, rax); 2123 StringCharFromCodeGenerator generator(code, rax);
2111 generator.GenerateFast(masm()); 2124 generator.GenerateFast(masm());
2112 __ ret(2 * kPointerSize); 2125 __ ret(2 * kPointerSize);
2113 2126
2114 StubRuntimeCallHelper call_helper; 2127 StubRuntimeCallHelper call_helper;
2115 generator.GenerateSlow(masm(), call_helper); 2128 generator.GenerateSlow(masm(), call_helper);
2116 2129
2130 // Tail call the full function. We do not have to patch the receiver
2131 // because the function makes no use of it.
2117 __ bind(&slow); 2132 __ bind(&slow);
2118 // We do not have to patch the receiver because the function makes no use of 2133 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2119 // it. 2134 ? CALL_AS_FUNCTION
2120 GenerateJumpFunctionIgnoreReceiver(function); 2135 : CALL_AS_METHOD;
2136 ParameterCount expected(function);
2137 __ InvokeFunction(function, expected, arguments(),
2138 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2121 2139
2122 HandlerFrontendFooter(&miss); 2140 HandlerFrontendFooter(&miss);
2123 2141
2124 // Return the generated code. 2142 // Return the generated code.
2125 return GetCode(type, name); 2143 return GetCode(type, name);
2126 } 2144 }
2127 2145
2128 2146
2129 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2147 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2130 Handle<Object> object, 2148 Handle<Object> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2213 // Return a new heap number. 2231 // Return a new heap number.
2214 __ AllocateHeapNumber(rax, rbx, &slow); 2232 __ AllocateHeapNumber(rax, rbx, &slow);
2215 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 2233 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
2216 __ ret(2 * kPointerSize); 2234 __ ret(2 * kPointerSize);
2217 2235
2218 // Return the argument (when it's an already round heap number). 2236 // Return the argument (when it's an already round heap number).
2219 __ bind(&already_round); 2237 __ bind(&already_round);
2220 __ movq(rax, args.GetArgumentOperand(1)); 2238 __ movq(rax, args.GetArgumentOperand(1));
2221 __ ret(2 * kPointerSize); 2239 __ ret(2 * kPointerSize);
2222 2240
2241 // Tail call the full function. We do not have to patch the receiver
2242 // because the function makes no use of it.
2223 __ bind(&slow); 2243 __ bind(&slow);
2224 // We do not have to patch the receiver because the function makes no use of 2244 ParameterCount expected(function);
2225 // it. 2245 __ InvokeFunction(function, expected, arguments(),
2226 GenerateJumpFunctionIgnoreReceiver(function); 2246 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2227 2247
2228 HandlerFrontendFooter(&miss); 2248 HandlerFrontendFooter(&miss);
2229 2249
2230 // Return the generated code. 2250 // Return the generated code.
2231 return GetCode(type, name); 2251 return GetCode(type, name);
2232 } 2252 }
2233 2253
2234 2254
2235 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2255 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2236 Handle<Object> object, 2256 Handle<Object> object,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 __ ret(2 * kPointerSize); 2317 __ ret(2 * kPointerSize);
2298 2318
2299 // If the argument is negative, clear the sign, and return a new 2319 // If the argument is negative, clear the sign, and return a new
2300 // number. We still have the sign mask in rdi. 2320 // number. We still have the sign mask in rdi.
2301 __ bind(&negative_sign); 2321 __ bind(&negative_sign);
2302 __ xor_(rbx, rdi); 2322 __ xor_(rbx, rdi);
2303 __ AllocateHeapNumber(rax, rdx, &slow); 2323 __ AllocateHeapNumber(rax, rdx, &slow);
2304 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 2324 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
2305 __ ret(2 * kPointerSize); 2325 __ ret(2 * kPointerSize);
2306 2326
2327 // Tail call the full function. We do not have to patch the receiver
2328 // because the function makes no use of it.
2307 __ bind(&slow); 2329 __ bind(&slow);
2308 // We do not have to patch the receiver because the function makes no use of 2330 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2309 // it. 2331 ? CALL_AS_FUNCTION
2310 GenerateJumpFunctionIgnoreReceiver(function); 2332 : CALL_AS_METHOD;
2333 ParameterCount expected(function);
2334 __ InvokeFunction(function, expected, arguments(),
2335 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2311 2336
2312 HandlerFrontendFooter(&miss); 2337 HandlerFrontendFooter(&miss);
2313 2338
2314 // Return the generated code. 2339 // Return the generated code.
2315 return GetCode(type, name); 2340 return GetCode(type, name);
2316 } 2341 }
2317 2342
2318 2343
2319 Handle<Code> CallStubCompiler::CompileFastApiCall( 2344 Handle<Code> CallStubCompiler::CompileFastApiCall(
2320 const CallOptimization& optimization, 2345 const CallOptimization& optimization,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 // Move the return address on top of the stack. 2383 // Move the return address on top of the stack.
2359 __ movq(rax, 2384 __ movq(rax,
2360 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2385 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2361 __ movq(StackOperandForReturnAddress(0), rax); 2386 __ movq(StackOperandForReturnAddress(0), rax);
2362 2387
2363 GenerateFastApiCall(masm(), optimization, argc); 2388 GenerateFastApiCall(masm(), optimization, argc);
2364 2389
2365 __ bind(&miss); 2390 __ bind(&miss);
2366 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2391 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2367 2392
2368 HandlerFrontendFooter(&miss_before_stack_reserved); 2393 __ bind(&miss_before_stack_reserved);
2394 GenerateMissBranch();
2369 2395
2370 // Return the generated code. 2396 // Return the generated code.
2371 return GetCode(function); 2397 return GetCode(function);
2372 } 2398 }
2373 2399
2374 2400
2375 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2401 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2376 Label success; 2402 Label success;
2377 // Check that the object is a boolean. 2403 // Check that the object is a boolean.
2378 __ CompareRoot(object, Heap::kTrueValueRootIndex); 2404 __ CompareRoot(object, Heap::kTrueValueRootIndex);
2379 __ j(equal, &success); 2405 __ j(equal, &success);
2380 __ CompareRoot(object, Heap::kFalseValueRootIndex); 2406 __ CompareRoot(object, Heap::kFalseValueRootIndex);
2381 __ j(not_equal, miss); 2407 __ j(not_equal, miss);
2382 __ bind(&success); 2408 __ bind(&success);
2383 } 2409 }
2384 2410
2385 2411
2386 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2412 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2387 if (!object.is_null() && object->IsGlobalObject()) { 2413 if (object->IsGlobalObject()) {
2388 StackArgumentsAccessor args(rsp, arguments()); 2414 StackArgumentsAccessor args(rsp, arguments());
2389 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2415 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2390 __ movq(args.GetReceiverOperand(), rdx); 2416 __ movq(args.GetReceiverOperand(), rdx);
2391 } 2417 }
2392 } 2418 }
2393 2419
2394 2420
2395 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2421 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2396 Handle<JSObject> holder, 2422 Handle<JSObject> holder,
2397 Handle<Name> name, 2423 Handle<Name> name,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2466 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2492 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2467 reg = CheckPrototypes( 2493 reg = CheckPrototypes(
2468 IC::CurrentTypeOf(prototype, isolate()), 2494 IC::CurrentTypeOf(prototype, isolate()),
2469 rax, holder, rbx, rdx, rdi, name, miss); 2495 rax, holder, rbx, rdx, rdi, name, miss);
2470 } 2496 }
2471 2497
2472 return reg; 2498 return reg;
2473 } 2499 }
2474 2500
2475 2501
2476 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 2502 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2477 Register function, 2503 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2478 Label* miss) { 2504 ? CALL_AS_FUNCTION
2479 // Check that the function really is a function. 2505 : CALL_AS_METHOD;
2480 GenerateFunctionCheck(function, rbx, miss); 2506 ParameterCount expected(function);
2481 2507 __ InvokeFunction(function, expected, arguments(),
2482 if (!function.is(rdi)) __ movq(rdi, function); 2508 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2483 PatchGlobalProxy(object);
2484
2485 // Invoke the function.
2486 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2487 NullCallWrapper(), call_kind());
2488 } 2509 }
2489 2510
2490 2511
2512 Handle<Code> CallStubCompiler::CompileCallConstant(
2513 Handle<Object> object,
2514 Handle<JSObject> holder,
2515 Handle<Name> name,
2516 CheckType check,
2517 Handle<JSFunction> function) {
2518 if (HasCustomCallGenerator(function)) {
2519 Handle<Code> code = CompileCustomCall(object, holder,
2520 Handle<PropertyCell>::null(),
2521 function, Handle<String>::cast(name),
2522 Code::FAST);
2523 // A null handle means bail out to the regular compiler code below.
2524 if (!code.is_null()) return code;
2525 }
2526
2527 Label miss;
2528 HandlerFrontendHeader(object, holder, name, check, &miss);
2529 PatchGlobalProxy(object);
2530 CompileHandlerBackend(function);
2531 HandlerFrontendFooter(&miss);
2532
2533 // Return the generated code.
2534 return GetCode(function);
2535 }
2536
2537
2491 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2538 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2492 Handle<JSObject> holder, 2539 Handle<JSObject> holder,
2493 Handle<Name> name) { 2540 Handle<Name> name) {
2494 Label miss; 2541 Label miss;
2495 GenerateNameCheck(name, &miss); 2542 GenerateNameCheck(name, &miss);
2496 2543
2497 LookupResult lookup(isolate()); 2544 LookupResult lookup(isolate());
2498 LookupPostInterceptor(holder, name, &lookup); 2545 LookupPostInterceptor(holder, name, &lookup);
2499 2546
2500 // Get the receiver from the stack. 2547 // Get the receiver from the stack.
2501 StackArgumentsAccessor args(rsp, arguments()); 2548 StackArgumentsAccessor args(rsp, arguments());
2502 __ movq(rdx, args.GetReceiverOperand()); 2549 __ movq(rdx, args.GetReceiverOperand());
2503 2550
2504 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2551 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2505 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2552 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2506 &miss); 2553 &miss);
2507 2554
2508 // Restore receiver. 2555 // Restore receiver.
2509 __ movq(rdx, args.GetReceiverOperand()); 2556 __ movq(rdx, args.GetReceiverOperand());
2510 2557
2511 GenerateJumpFunction(object, rax, &miss); 2558 // Check that the function really is a function.
2559 __ JumpIfSmi(rax, &miss);
2560 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2561 __ j(not_equal, &miss);
2512 2562
2513 HandlerFrontendFooter(&miss); 2563 // Patch the receiver on the stack with the global proxy if
2564 // necessary.
2565 if (object->IsGlobalObject()) {
2566 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2567 __ movq(args.GetReceiverOperand(), rdx);
2568 }
2569
2570 // Invoke the function.
2571 __ movq(rdi, rax);
2572 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2573 ? CALL_AS_FUNCTION
2574 : CALL_AS_METHOD;
2575 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2576 NullCallWrapper(), call_kind);
2577
2578 // Handle load cache miss.
2579 __ bind(&miss);
2580 GenerateMissBranch();
2514 2581
2515 // Return the generated code. 2582 // Return the generated code.
2516 return GetCode(Code::FAST, name); 2583 return GetCode(Code::FAST, name);
2517 } 2584 }
2518 2585
2519 2586
2520 Handle<Code> CallStubCompiler::CompileCallGlobal( 2587 Handle<Code> CallStubCompiler::CompileCallGlobal(
2521 Handle<JSObject> object, 2588 Handle<JSObject> object,
2522 Handle<GlobalObject> holder, 2589 Handle<GlobalObject> holder,
2523 Handle<PropertyCell> cell, 2590 Handle<PropertyCell> cell,
2524 Handle<JSFunction> function, 2591 Handle<JSFunction> function,
2525 Handle<Name> name) { 2592 Handle<Name> name) {
2526 if (HasCustomCallGenerator(function)) { 2593 if (HasCustomCallGenerator(function)) {
2527 Handle<Code> code = CompileCustomCall( 2594 Handle<Code> code = CompileCustomCall(
2528 object, holder, cell, function, Handle<String>::cast(name), 2595 object, holder, cell, function, Handle<String>::cast(name),
2529 Code::NORMAL); 2596 Code::NORMAL);
2530 // A null handle means bail out to the regular compiler code below. 2597 // A null handle means bail out to the regular compiler code below.
2531 if (!code.is_null()) return code; 2598 if (!code.is_null()) return code;
2532 } 2599 }
2533 2600
2534 Label miss; 2601 Label miss;
2535 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2602 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2536 // Potentially loads a closure that matches the shared function info of the
2537 // function, rather than function.
2538 GenerateLoadFunctionFromCell(cell, function, &miss); 2603 GenerateLoadFunctionFromCell(cell, function, &miss);
2604 PatchGlobalProxy(object);
2605
2606 // Set up the context (function already in rdi).
2607 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2608
2609 // Jump to the cached code (tail call).
2539 Counters* counters = isolate()->counters(); 2610 Counters* counters = isolate()->counters();
2540 __ IncrementCounter(counters->call_global_inline(), 1); 2611 __ IncrementCounter(counters->call_global_inline(), 1);
2541 GenerateJumpFunction(object, rdi, function); 2612 ParameterCount expected(function->shared()->formal_parameter_count());
2613 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2614 ? CALL_AS_FUNCTION
2615 : CALL_AS_METHOD;
2616 // We call indirectly through the code field in the function to
2617 // allow recompilation to take effect without changing any of the
2618 // call sites.
2619 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2620 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2621 NullCallWrapper(), call_kind);
2622
2542 HandlerFrontendFooter(&miss); 2623 HandlerFrontendFooter(&miss);
2543 2624
2544 // Return the generated code. 2625 // Return the generated code.
2545 return GetCode(Code::NORMAL, name); 2626 return GetCode(Code::NORMAL, name);
2546 } 2627 }
2547 2628
2548 2629
2549 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2630 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2550 Handle<JSObject> object, 2631 Handle<JSObject> object,
2551 Handle<JSObject> holder, 2632 Handle<JSObject> holder,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2915 // ----------------------------------- 2996 // -----------------------------------
2916 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2997 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2917 } 2998 }
2918 2999
2919 3000
2920 #undef __ 3001 #undef __
2921 3002
2922 } } // namespace v8::internal 3003 } } // namespace v8::internal
2923 3004
2924 #endif // V8_TARGET_ARCH_X64 3005 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698