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

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

Issue 96763002: Reupload CallIC changes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments 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(StubCompiler* stub_compiler, 640 CallInterceptorCompiler(CallStubCompiler* 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;
754 Handle<JSFunction> fun = optimization.constant_function(); 751 Handle<JSFunction> fun = optimization.constant_function();
755 ParameterCount expected(fun); 752 stub_compiler_->GenerateJumpFunctionIgnoreReceiver(fun);
756 __ InvokeFunction(fun, expected, arguments_,
757 JUMP_FUNCTION, NullCallWrapper(), call_kind);
758 } 753 }
759 754
760 // Deferred code for fast API call case---clean preallocated space. 755 // Deferred code for fast API call case---clean preallocated space.
761 if (can_do_fast_api_call) { 756 if (can_do_fast_api_call) {
762 __ bind(&miss_cleanup); 757 __ bind(&miss_cleanup);
763 FreeSpaceForFastApiCall(masm, scratch1); 758 FreeSpaceForFastApiCall(masm, scratch1);
764 __ jmp(miss_label); 759 __ jmp(miss_label);
765 } 760 }
766 761
767 // Invoke a regular function. 762 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 810
816 __ pop(name_); // Restore the name. 811 __ pop(name_); // Restore the name.
817 __ pop(receiver); // Restore the holder. 812 __ pop(receiver); // Restore the holder.
818 // Leave the internal frame. 813 // Leave the internal frame.
819 } 814 }
820 815
821 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 816 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
822 __ j(not_equal, interceptor_succeeded); 817 __ j(not_equal, interceptor_succeeded);
823 } 818 }
824 819
825 StubCompiler* stub_compiler_; 820 CallStubCompiler* stub_compiler_;
826 const ParameterCount& arguments_; 821 const ParameterCount& arguments_;
827 Register name_; 822 Register name_;
828 ExtraICState extra_ic_state_; 823 ExtraICState extra_ic_state_;
829 }; 824 };
830 825
831 826
832 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 827 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
833 Label* label, 828 Label* label,
834 Handle<Name> name) { 829 Handle<Name> name) {
835 if (!label->is_unused()) { 830 if (!label->is_unused()) {
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 1525
1531 1526
1532 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1527 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1533 if (kind_ == Code::KEYED_CALL_IC) { 1528 if (kind_ == Code::KEYED_CALL_IC) {
1534 __ Cmp(rcx, name); 1529 __ Cmp(rcx, name);
1535 __ j(not_equal, miss); 1530 __ j(not_equal, miss);
1536 } 1531 }
1537 } 1532 }
1538 1533
1539 1534
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
1540 void CallStubCompiler::GenerateLoadFunctionFromCell( 1544 void CallStubCompiler::GenerateLoadFunctionFromCell(
1541 Handle<Cell> cell, 1545 Handle<Cell> cell,
1542 Handle<JSFunction> function, 1546 Handle<JSFunction> function,
1543 Label* miss) { 1547 Label* miss) {
1544 // Get the value from the cell. 1548 // Get the value from the cell.
1545 __ Move(rdi, cell); 1549 __ Move(rdi, cell);
1546 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1550 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
1547 1551
1548 // Check that the cell contains the same function. 1552 // Check that the cell contains the same function.
1549 if (heap()->InNewSpace(*function)) { 1553 if (heap()->InNewSpace(*function)) {
1550 // We can't embed a pointer to a function in new space so we have 1554 // We can't embed a pointer to a function in new space so we have
1551 // to verify that the shared function info is unchanged. This has 1555 // to verify that the shared function info is unchanged. This has
1552 // the nice side effect that multiple closures based on the same 1556 // the nice side effect that multiple closures based on the same
1553 // function can all use this call IC. Before we load through the 1557 // function can all use this call IC. Before we load through the
1554 // function, we have to verify that it still is a function. 1558 // function, we have to verify that it still is a function.
1555 __ JumpIfSmi(rdi, miss); 1559 GenerateFunctionCheck(rdi, rax, miss);
1556 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
1557 __ j(not_equal, miss);
1558 1560
1559 // Check the shared function info. Make sure it hasn't changed. 1561 // Check the shared function info. Make sure it hasn't changed.
1560 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1562 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1561 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1563 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1562 } else { 1564 } else {
1563 __ Cmp(rdi, function); 1565 __ Cmp(rdi, function);
1564 } 1566 }
1565 __ j(not_equal, miss); 1567 __ j(not_equal, miss);
1566 } 1568 }
1567 1569
(...skipping 11 matching lines...) Expand all
1579 Handle<JSObject> holder, 1581 Handle<JSObject> holder,
1580 PropertyIndex index, 1582 PropertyIndex index,
1581 Handle<Name> name) { 1583 Handle<Name> name) {
1582 Label miss; 1584 Label miss;
1583 1585
1584 Register reg = HandlerFrontendHeader( 1586 Register reg = HandlerFrontendHeader(
1585 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1587 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1586 1588
1587 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1589 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1588 index.translate(holder), Representation::Tagged()); 1590 index.translate(holder), Representation::Tagged());
1589 1591 GenerateJumpFunction(object, rdi, &miss);
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);
1603 1592
1604 HandlerFrontendFooter(&miss); 1593 HandlerFrontendFooter(&miss);
1605 1594
1606 // Return the generated code. 1595 // Return the generated code.
1607 return GetCode(Code::FAST, name); 1596 return GetCode(Code::FAST, name);
1608 } 1597 }
1609 1598
1610 1599
1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1600 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1612 Handle<Object> object, 1601 Handle<Object> object,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 1996
2008 if (index_out_of_range.is_linked()) { 1997 if (index_out_of_range.is_linked()) {
2009 __ bind(&index_out_of_range); 1998 __ bind(&index_out_of_range);
2010 __ LoadRoot(rax, Heap::kNanValueRootIndex); 1999 __ LoadRoot(rax, Heap::kNanValueRootIndex);
2011 __ ret((argc + 1) * kPointerSize); 2000 __ ret((argc + 1) * kPointerSize);
2012 } 2001 }
2013 2002
2014 __ bind(&miss); 2003 __ bind(&miss);
2015 // Restore function name in rcx. 2004 // Restore function name in rcx.
2016 __ Move(rcx, name); 2005 __ Move(rcx, name);
2017 __ bind(&name_miss); 2006 HandlerFrontendFooter(&name_miss);
2018 GenerateMissBranch();
2019 2007
2020 // Return the generated code. 2008 // Return the generated code.
2021 return GetCode(type, name); 2009 return GetCode(type, name);
2022 } 2010 }
2023 2011
2024 2012
2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2013 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2026 Handle<Object> object, 2014 Handle<Object> object,
2027 Handle<JSObject> holder, 2015 Handle<JSObject> holder,
2028 Handle<Cell> cell, 2016 Handle<Cell> cell,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 generator.GenerateSlow(masm(), call_helper); 2061 generator.GenerateSlow(masm(), call_helper);
2074 2062
2075 if (index_out_of_range.is_linked()) { 2063 if (index_out_of_range.is_linked()) {
2076 __ bind(&index_out_of_range); 2064 __ bind(&index_out_of_range);
2077 __ LoadRoot(rax, Heap::kempty_stringRootIndex); 2065 __ LoadRoot(rax, Heap::kempty_stringRootIndex);
2078 __ ret((argc + 1) * kPointerSize); 2066 __ ret((argc + 1) * kPointerSize);
2079 } 2067 }
2080 __ bind(&miss); 2068 __ bind(&miss);
2081 // Restore function name in rcx. 2069 // Restore function name in rcx.
2082 __ Move(rcx, name); 2070 __ Move(rcx, name);
2083 __ bind(&name_miss); 2071 HandlerFrontendFooter(&name_miss);
2084 GenerateMissBranch();
2085 2072
2086 // Return the generated code. 2073 // Return the generated code.
2087 return GetCode(type, name); 2074 return GetCode(type, name);
2088 } 2075 }
2089 2076
2090 2077
2091 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2078 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2092 Handle<Object> object, 2079 Handle<Object> object,
2093 Handle<JSObject> holder, 2080 Handle<JSObject> holder,
2094 Handle<Cell> cell, 2081 Handle<Cell> cell,
(...skipping 25 matching lines...) Expand all
2120 // Convert the smi code to uint16. 2107 // Convert the smi code to uint16.
2121 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2108 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2122 2109
2123 StringCharFromCodeGenerator generator(code, rax); 2110 StringCharFromCodeGenerator generator(code, rax);
2124 generator.GenerateFast(masm()); 2111 generator.GenerateFast(masm());
2125 __ ret(2 * kPointerSize); 2112 __ ret(2 * kPointerSize);
2126 2113
2127 StubRuntimeCallHelper call_helper; 2114 StubRuntimeCallHelper call_helper;
2128 generator.GenerateSlow(masm(), call_helper); 2115 generator.GenerateSlow(masm(), call_helper);
2129 2116
2130 // Tail call the full function. We do not have to patch the receiver
2131 // because the function makes no use of it.
2132 __ bind(&slow); 2117 __ bind(&slow);
2133 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2118 // We do not have to patch the receiver because the function makes no use of
2134 ? CALL_AS_FUNCTION 2119 // it.
2135 : CALL_AS_METHOD; 2120 GenerateJumpFunctionIgnoreReceiver(function);
2136 ParameterCount expected(function);
2137 __ InvokeFunction(function, expected, arguments(),
2138 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2139 2121
2140 HandlerFrontendFooter(&miss); 2122 HandlerFrontendFooter(&miss);
2141 2123
2142 // Return the generated code. 2124 // Return the generated code.
2143 return GetCode(type, name); 2125 return GetCode(type, name);
2144 } 2126 }
2145 2127
2146 2128
2147 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2129 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2148 Handle<Object> object, 2130 Handle<Object> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 // Return a new heap number. 2213 // Return a new heap number.
2232 __ AllocateHeapNumber(rax, rbx, &slow); 2214 __ AllocateHeapNumber(rax, rbx, &slow);
2233 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 2215 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
2234 __ ret(2 * kPointerSize); 2216 __ ret(2 * kPointerSize);
2235 2217
2236 // Return the argument (when it's an already round heap number). 2218 // Return the argument (when it's an already round heap number).
2237 __ bind(&already_round); 2219 __ bind(&already_round);
2238 __ movq(rax, args.GetArgumentOperand(1)); 2220 __ movq(rax, args.GetArgumentOperand(1));
2239 __ ret(2 * kPointerSize); 2221 __ ret(2 * kPointerSize);
2240 2222
2241 // Tail call the full function. We do not have to patch the receiver
2242 // because the function makes no use of it.
2243 __ bind(&slow); 2223 __ bind(&slow);
2244 ParameterCount expected(function); 2224 // We do not have to patch the receiver because the function makes no use of
2245 __ InvokeFunction(function, expected, arguments(), 2225 // it.
2246 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2226 GenerateJumpFunctionIgnoreReceiver(function);
2247 2227
2248 HandlerFrontendFooter(&miss); 2228 HandlerFrontendFooter(&miss);
2249 2229
2250 // Return the generated code. 2230 // Return the generated code.
2251 return GetCode(type, name); 2231 return GetCode(type, name);
2252 } 2232 }
2253 2233
2254 2234
2255 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2235 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2256 Handle<Object> object, 2236 Handle<Object> object,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 __ ret(2 * kPointerSize); 2297 __ ret(2 * kPointerSize);
2318 2298
2319 // If the argument is negative, clear the sign, and return a new 2299 // If the argument is negative, clear the sign, and return a new
2320 // number. We still have the sign mask in rdi. 2300 // number. We still have the sign mask in rdi.
2321 __ bind(&negative_sign); 2301 __ bind(&negative_sign);
2322 __ xor_(rbx, rdi); 2302 __ xor_(rbx, rdi);
2323 __ AllocateHeapNumber(rax, rdx, &slow); 2303 __ AllocateHeapNumber(rax, rdx, &slow);
2324 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 2304 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
2325 __ ret(2 * kPointerSize); 2305 __ ret(2 * kPointerSize);
2326 2306
2327 // Tail call the full function. We do not have to patch the receiver
2328 // because the function makes no use of it.
2329 __ bind(&slow); 2307 __ bind(&slow);
2330 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2308 // We do not have to patch the receiver because the function makes no use of
2331 ? CALL_AS_FUNCTION 2309 // it.
2332 : CALL_AS_METHOD; 2310 GenerateJumpFunctionIgnoreReceiver(function);
2333 ParameterCount expected(function);
2334 __ InvokeFunction(function, expected, arguments(),
2335 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2336 2311
2337 HandlerFrontendFooter(&miss); 2312 HandlerFrontendFooter(&miss);
2338 2313
2339 // Return the generated code. 2314 // Return the generated code.
2340 return GetCode(type, name); 2315 return GetCode(type, name);
2341 } 2316 }
2342 2317
2343 2318
2344 Handle<Code> CallStubCompiler::CompileFastApiCall( 2319 Handle<Code> CallStubCompiler::CompileFastApiCall(
2345 const CallOptimization& optimization, 2320 const CallOptimization& optimization,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2383 // Move the return address on top of the stack. 2358 // Move the return address on top of the stack.
2384 __ movq(rax, 2359 __ movq(rax,
2385 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2360 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2386 __ movq(StackOperandForReturnAddress(0), rax); 2361 __ movq(StackOperandForReturnAddress(0), rax);
2387 2362
2388 GenerateFastApiCall(masm(), optimization, argc); 2363 GenerateFastApiCall(masm(), optimization, argc);
2389 2364
2390 __ bind(&miss); 2365 __ bind(&miss);
2391 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2366 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2392 2367
2393 __ bind(&miss_before_stack_reserved); 2368 HandlerFrontendFooter(&miss_before_stack_reserved);
2394 GenerateMissBranch();
2395 2369
2396 // Return the generated code. 2370 // Return the generated code.
2397 return GetCode(function); 2371 return GetCode(function);
2398 } 2372 }
2399 2373
2400 2374
2401 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2375 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2402 Label success; 2376 Label success;
2403 // Check that the object is a boolean. 2377 // Check that the object is a boolean.
2404 __ CompareRoot(object, Heap::kTrueValueRootIndex); 2378 __ CompareRoot(object, Heap::kTrueValueRootIndex);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2466 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2493 reg = CheckPrototypes( 2467 reg = CheckPrototypes(
2494 IC::CurrentTypeOf(prototype, isolate()), 2468 IC::CurrentTypeOf(prototype, isolate()),
2495 rax, holder, rbx, rdx, rdi, name, miss); 2469 rax, holder, rbx, rdx, rdi, name, miss);
2496 } 2470 }
2497 2471
2498 return reg; 2472 return reg;
2499 } 2473 }
2500 2474
2501 2475
2502 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2476 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
2503 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2477 Register function,
2504 ? CALL_AS_FUNCTION 2478 Label* miss) {
2505 : CALL_AS_METHOD; 2479 // Check that the function really is a function.
2506 ParameterCount expected(function); 2480 GenerateFunctionCheck(function, rbx, miss);
2507 __ InvokeFunction(function, expected, arguments(), 2481
2508 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2482 if (!function.is(rdi)) __ movq(rdi, function);
2483 PatchGlobalProxy(object);
2484
2485 // Invoke the function.
2486 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2487 NullCallWrapper(), call_kind());
2509 } 2488 }
2510 2489
2511 2490
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
2538 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2491 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2539 Handle<JSObject> holder, 2492 Handle<JSObject> holder,
2540 Handle<Name> name) { 2493 Handle<Name> name) {
2541 Label miss; 2494 Label miss;
2542 GenerateNameCheck(name, &miss); 2495 GenerateNameCheck(name, &miss);
2543 2496
2544 LookupResult lookup(isolate()); 2497 LookupResult lookup(isolate());
2545 LookupPostInterceptor(holder, name, &lookup); 2498 LookupPostInterceptor(holder, name, &lookup);
2546 2499
2547 // Get the receiver from the stack. 2500 // Get the receiver from the stack.
2548 StackArgumentsAccessor args(rsp, arguments()); 2501 StackArgumentsAccessor args(rsp, arguments());
2549 __ movq(rdx, args.GetReceiverOperand()); 2502 __ movq(rdx, args.GetReceiverOperand());
2550 2503
2551 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2504 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2552 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2505 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2553 &miss); 2506 &miss);
2554 2507
2555 // Restore receiver. 2508 // Restore receiver.
2556 __ movq(rdx, args.GetReceiverOperand()); 2509 __ movq(rdx, args.GetReceiverOperand());
2557 2510
2558 // Check that the function really is a function. 2511 GenerateJumpFunction(object, rax, &miss);
2559 __ JumpIfSmi(rax, &miss);
2560 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2561 __ j(not_equal, &miss);
2562 2512
2563 // Patch the receiver on the stack with the global proxy if 2513 HandlerFrontendFooter(&miss);
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();
2581 2514
2582 // Return the generated code. 2515 // Return the generated code.
2583 return GetCode(Code::FAST, name); 2516 return GetCode(Code::FAST, name);
2584 } 2517 }
2585 2518
2586 2519
2587 Handle<Code> CallStubCompiler::CompileCallGlobal( 2520 Handle<Code> CallStubCompiler::CompileCallGlobal(
2588 Handle<JSObject> object, 2521 Handle<JSObject> object,
2589 Handle<GlobalObject> holder, 2522 Handle<GlobalObject> holder,
2590 Handle<PropertyCell> cell, 2523 Handle<PropertyCell> cell,
2591 Handle<JSFunction> function, 2524 Handle<JSFunction> function,
2592 Handle<Name> name) { 2525 Handle<Name> name) {
2593 if (HasCustomCallGenerator(function)) { 2526 if (HasCustomCallGenerator(function)) {
2594 Handle<Code> code = CompileCustomCall( 2527 Handle<Code> code = CompileCustomCall(
2595 object, holder, cell, function, Handle<String>::cast(name), 2528 object, holder, cell, function, Handle<String>::cast(name),
2596 Code::NORMAL); 2529 Code::NORMAL);
2597 // A null handle means bail out to the regular compiler code below. 2530 // A null handle means bail out to the regular compiler code below.
2598 if (!code.is_null()) return code; 2531 if (!code.is_null()) return code;
2599 } 2532 }
2600 2533
2601 Label miss; 2534 Label miss;
2602 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2535 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.
2603 GenerateLoadFunctionFromCell(cell, function, &miss); 2538 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).
2610 Counters* counters = isolate()->counters(); 2539 Counters* counters = isolate()->counters();
2611 __ IncrementCounter(counters->call_global_inline(), 1); 2540 __ IncrementCounter(counters->call_global_inline(), 1);
2612 ParameterCount expected(function->shared()->formal_parameter_count()); 2541 GenerateJumpFunction(object, rdi, function);
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
2623 HandlerFrontendFooter(&miss); 2542 HandlerFrontendFooter(&miss);
2624 2543
2625 // Return the generated code. 2544 // Return the generated code.
2626 return GetCode(Code::NORMAL, name); 2545 return GetCode(Code::NORMAL, name);
2627 } 2546 }
2628 2547
2629 2548
2630 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2549 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2631 Handle<JSObject> object, 2550 Handle<JSObject> object,
2632 Handle<JSObject> holder, 2551 Handle<JSObject> holder,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 // ----------------------------------- 2915 // -----------------------------------
2997 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2916 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2998 } 2917 }
2999 2918
3000 2919
3001 #undef __ 2920 #undef __
3002 2921
3003 } } // namespace v8::internal 2922 } } // namespace v8::internal
3004 2923
3005 #endif // V8_TARGET_ARCH_X64 2924 #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