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

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

Issue 91963003: Cleanup in the CallStubCompiler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix check 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
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 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 thunk_address, 635 thunk_address,
636 callback_arg, 636 callback_arg,
637 argc + kFastApiCallArguments + 1, 637 argc + kFastApiCallArguments + 1,
638 return_value_operand, 638 return_value_operand,
639 restore_context ? &context_restore_operand : NULL); 639 restore_context ? &context_restore_operand : NULL);
640 } 640 }
641 641
642 642
643 class CallInterceptorCompiler BASE_EMBEDDED { 643 class CallInterceptorCompiler BASE_EMBEDDED {
644 public: 644 public:
645 CallInterceptorCompiler(StubCompiler* stub_compiler, 645 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
646 const ParameterCount& arguments, 646 const ParameterCount& arguments,
647 Register name, 647 Register name,
648 Code::ExtraICState extra_ic_state) 648 Code::ExtraICState extra_ic_state)
649 : stub_compiler_(stub_compiler), 649 : stub_compiler_(stub_compiler),
650 arguments_(arguments), 650 arguments_(arguments),
651 name_(name), 651 name_(name),
652 extra_ic_state_(extra_ic_state) {} 652 extra_ic_state_(extra_ic_state) {}
653 653
654 void Compile(MacroAssembler* masm, 654 void Compile(MacroAssembler* masm,
655 Handle<JSObject> object, 655 Handle<JSObject> object,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // for API (object which is instanceof for the signature). It's 746 // for API (object which is instanceof for the signature). It's
747 // safe to omit it here, as if present, it should be fetched 747 // safe to omit it here, as if present, it should be fetched
748 // by the previous CheckPrototypes. 748 // by the previous CheckPrototypes.
749 ASSERT(depth2 == kInvalidProtoDepth); 749 ASSERT(depth2 == kInvalidProtoDepth);
750 } 750 }
751 751
752 // Invoke function. 752 // Invoke function.
753 if (can_do_fast_api_call) { 753 if (can_do_fast_api_call) {
754 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 754 GenerateFastApiCall(masm, optimization, arguments_.immediate());
755 } else { 755 } else {
756 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
757 ? CALL_AS_FUNCTION
758 : CALL_AS_METHOD;
759 Handle<JSFunction> fun = optimization.constant_function(); 756 Handle<JSFunction> fun = optimization.constant_function();
760 ParameterCount expected(fun); 757 stub_compiler_->GenerateCallFunction(object, fun);
761 __ InvokeFunction(fun, expected, arguments_,
762 JUMP_FUNCTION, NullCallWrapper(), call_kind);
763 } 758 }
764 759
765 // Deferred code for fast API call case---clean preallocated space. 760 // Deferred code for fast API call case---clean preallocated space.
766 if (can_do_fast_api_call) { 761 if (can_do_fast_api_call) {
767 __ bind(&miss_cleanup); 762 __ bind(&miss_cleanup);
768 FreeSpaceForFastApiCall(masm, scratch1); 763 FreeSpaceForFastApiCall(masm, scratch1);
769 __ jmp(miss_label); 764 __ jmp(miss_label);
770 } 765 }
771 766
772 // Invoke a regular function. 767 // Invoke a regular function.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 820
826 __ pop(name_); // Restore the name. 821 __ pop(name_); // Restore the name.
827 __ pop(receiver); // Restore the holder. 822 __ pop(receiver); // Restore the holder.
828 // Leave the internal frame. 823 // Leave the internal frame.
829 } 824 }
830 825
831 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 826 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
832 __ j(not_equal, interceptor_succeeded); 827 __ j(not_equal, interceptor_succeeded);
833 } 828 }
834 829
835 StubCompiler* stub_compiler_; 830 CallStubCompiler* stub_compiler_;
836 const ParameterCount& arguments_; 831 const ParameterCount& arguments_;
837 Register name_; 832 Register name_;
838 Code::ExtraICState extra_ic_state_; 833 Code::ExtraICState extra_ic_state_;
839 }; 834 };
840 835
841 836
842 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 837 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
843 Label* label, 838 Label* label,
844 Handle<Name> name) { 839 Handle<Name> name) {
845 if (!label->is_unused()) { 840 if (!label->is_unused()) {
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1537
1543 1538
1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1539 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1545 if (kind_ == Code::KEYED_CALL_IC) { 1540 if (kind_ == Code::KEYED_CALL_IC) {
1546 __ Cmp(rcx, name); 1541 __ Cmp(rcx, name);
1547 __ j(not_equal, miss); 1542 __ j(not_equal, miss);
1548 } 1543 }
1549 } 1544 }
1550 1545
1551 1546
1547 void CallStubCompiler::GenerateFunctionCheck(Register function,
1548 Register scratch,
1549 Label* miss) {
1550 __ JumpIfSmi(function, miss);
1551 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1552 __ j(not_equal, miss);
1553 }
1554
1555
1552 void CallStubCompiler::GenerateLoadFunctionFromCell( 1556 void CallStubCompiler::GenerateLoadFunctionFromCell(
1553 Handle<Cell> cell, 1557 Handle<Cell> cell,
1554 Handle<JSFunction> function, 1558 Handle<JSFunction> function,
1555 Label* miss) { 1559 Label* miss) {
1556 // Get the value from the cell. 1560 // Get the value from the cell.
1557 __ Move(rdi, cell); 1561 __ Move(rdi, cell);
1558 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 1562 __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset));
1559 1563
1560 // Check that the cell contains the same function. 1564 // Check that the cell contains the same function.
1561 if (heap()->InNewSpace(*function)) { 1565 if (heap()->InNewSpace(*function)) {
1562 // We can't embed a pointer to a function in new space so we have 1566 // We can't embed a pointer to a function in new space so we have
1563 // to verify that the shared function info is unchanged. This has 1567 // to verify that the shared function info is unchanged. This has
1564 // the nice side effect that multiple closures based on the same 1568 // the nice side effect that multiple closures based on the same
1565 // function can all use this call IC. Before we load through the 1569 // function can all use this call IC. Before we load through the
1566 // function, we have to verify that it still is a function. 1570 // function, we have to verify that it still is a function.
1567 __ JumpIfSmi(rdi, miss); 1571 GenerateFunctionCheck(rdi, rax, miss);
1568 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
1569 __ j(not_equal, miss);
1570 1572
1571 // Check the shared function info. Make sure it hasn't changed. 1573 // Check the shared function info. Make sure it hasn't changed.
1572 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 1574 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
1573 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 1575 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
1574 } else { 1576 } else {
1575 __ Cmp(rdi, function); 1577 __ Cmp(rdi, function);
1576 } 1578 }
1577 __ j(not_equal, miss); 1579 __ j(not_equal, miss);
1578 } 1580 }
1579 1581
(...skipping 11 matching lines...) Expand all
1591 Handle<JSObject> holder, 1593 Handle<JSObject> holder,
1592 PropertyIndex index, 1594 PropertyIndex index,
1593 Handle<Name> name) { 1595 Handle<Name> name) {
1594 Label miss; 1596 Label miss;
1595 1597
1596 Register reg = HandlerFrontendHeader( 1598 Register reg = HandlerFrontendHeader(
1597 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1599 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1598 1600
1599 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 1601 GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder),
1600 index.translate(holder), Representation::Tagged()); 1602 index.translate(holder), Representation::Tagged());
1601 1603 GenerateCallFunction(object, rdi, &miss);
1602 // Check that the function really is a function.
1603 __ JumpIfSmi(rdi, &miss);
1604 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
1605 __ j(not_equal, &miss);
1606
1607 PatchGlobalProxy(object);
1608
1609 // Invoke the function.
1610 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1611 ? CALL_AS_FUNCTION
1612 : CALL_AS_METHOD;
1613 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1614 NullCallWrapper(), call_kind);
1615 1604
1616 HandlerFrontendFooter(&miss); 1605 HandlerFrontendFooter(&miss);
1617 1606
1618 // Return the generated code. 1607 // Return the generated code.
1619 return GetCode(Code::FAST, name); 1608 return GetCode(Code::FAST, name);
1620 } 1609 }
1621 1610
1622 1611
1623 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1612 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1624 Handle<Object> object, 1613 Handle<Object> object,
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 2008
2020 if (index_out_of_range.is_linked()) { 2009 if (index_out_of_range.is_linked()) {
2021 __ bind(&index_out_of_range); 2010 __ bind(&index_out_of_range);
2022 __ LoadRoot(rax, Heap::kNanValueRootIndex); 2011 __ LoadRoot(rax, Heap::kNanValueRootIndex);
2023 __ ret((argc + 1) * kPointerSize); 2012 __ ret((argc + 1) * kPointerSize);
2024 } 2013 }
2025 2014
2026 __ bind(&miss); 2015 __ bind(&miss);
2027 // Restore function name in rcx. 2016 // Restore function name in rcx.
2028 __ Move(rcx, name); 2017 __ Move(rcx, name);
2029 __ bind(&name_miss); 2018 HandlerFrontendFooter(&name_miss);
2030 GenerateMissBranch();
2031 2019
2032 // Return the generated code. 2020 // Return the generated code.
2033 return GetCode(type, name); 2021 return GetCode(type, name);
2034 } 2022 }
2035 2023
2036 2024
2037 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2038 Handle<Object> object, 2026 Handle<Object> object,
2039 Handle<JSObject> holder, 2027 Handle<JSObject> holder,
2040 Handle<Cell> cell, 2028 Handle<Cell> cell,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2085 generator.GenerateSlow(masm(), call_helper); 2073 generator.GenerateSlow(masm(), call_helper);
2086 2074
2087 if (index_out_of_range.is_linked()) { 2075 if (index_out_of_range.is_linked()) {
2088 __ bind(&index_out_of_range); 2076 __ bind(&index_out_of_range);
2089 __ LoadRoot(rax, Heap::kempty_stringRootIndex); 2077 __ LoadRoot(rax, Heap::kempty_stringRootIndex);
2090 __ ret((argc + 1) * kPointerSize); 2078 __ ret((argc + 1) * kPointerSize);
2091 } 2079 }
2092 __ bind(&miss); 2080 __ bind(&miss);
2093 // Restore function name in rcx. 2081 // Restore function name in rcx.
2094 __ Move(rcx, name); 2082 __ Move(rcx, name);
2095 __ bind(&name_miss); 2083 HandlerFrontendFooter(&name_miss);
2096 GenerateMissBranch();
2097 2084
2098 // Return the generated code. 2085 // Return the generated code.
2099 return GetCode(type, name); 2086 return GetCode(type, name);
2100 } 2087 }
2101 2088
2102 2089
2103 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2090 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2104 Handle<Object> object, 2091 Handle<Object> object,
2105 Handle<JSObject> holder, 2092 Handle<JSObject> holder,
2106 Handle<Cell> cell, 2093 Handle<Cell> cell,
(...skipping 25 matching lines...) Expand all
2132 // Convert the smi code to uint16. 2119 // Convert the smi code to uint16.
2133 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2120 __ SmiAndConstant(code, code, Smi::FromInt(0xffff));
2134 2121
2135 StringCharFromCodeGenerator generator(code, rax); 2122 StringCharFromCodeGenerator generator(code, rax);
2136 generator.GenerateFast(masm()); 2123 generator.GenerateFast(masm());
2137 __ ret(2 * kPointerSize); 2124 __ ret(2 * kPointerSize);
2138 2125
2139 StubRuntimeCallHelper call_helper; 2126 StubRuntimeCallHelper call_helper;
2140 generator.GenerateSlow(masm(), call_helper); 2127 generator.GenerateSlow(masm(), call_helper);
2141 2128
2142 // Tail call the full function. We do not have to patch the receiver
2143 // because the function makes no use of it.
2144 __ bind(&slow); 2129 __ bind(&slow);
2145 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2130 // We do not have to patch the receiver because the function makes no use of
2146 ? CALL_AS_FUNCTION 2131 // it.
2147 : CALL_AS_METHOD; 2132 GenerateCallFunction(Handle<Object>::null(), function);
2148 ParameterCount expected(function);
2149 __ InvokeFunction(function, expected, arguments(),
2150 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2151 2133
2152 HandlerFrontendFooter(&miss); 2134 HandlerFrontendFooter(&miss);
2153 2135
2154 // Return the generated code. 2136 // Return the generated code.
2155 return GetCode(type, name); 2137 return GetCode(type, name);
2156 } 2138 }
2157 2139
2158 2140
2159 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2141 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2160 Handle<Object> object, 2142 Handle<Object> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2243 // Return a new heap number. 2225 // Return a new heap number.
2244 __ AllocateHeapNumber(rax, rbx, &slow); 2226 __ AllocateHeapNumber(rax, rbx, &slow);
2245 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 2227 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0);
2246 __ ret(2 * kPointerSize); 2228 __ ret(2 * kPointerSize);
2247 2229
2248 // Return the argument (when it's an already round heap number). 2230 // Return the argument (when it's an already round heap number).
2249 __ bind(&already_round); 2231 __ bind(&already_round);
2250 __ movq(rax, args.GetArgumentOperand(1)); 2232 __ movq(rax, args.GetArgumentOperand(1));
2251 __ ret(2 * kPointerSize); 2233 __ ret(2 * kPointerSize);
2252 2234
2253 // Tail call the full function. We do not have to patch the receiver
2254 // because the function makes no use of it.
2255 __ bind(&slow); 2235 __ bind(&slow);
2256 ParameterCount expected(function); 2236 // We do not have to patch the receiver because the function makes no use of
2257 __ InvokeFunction(function, expected, arguments(), 2237 // it.
2258 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2238 GenerateCallFunction(Handle<Object>::null(), function);
2259 2239
2260 HandlerFrontendFooter(&miss); 2240 HandlerFrontendFooter(&miss);
2261 2241
2262 // Return the generated code. 2242 // Return the generated code.
2263 return GetCode(type, name); 2243 return GetCode(type, name);
2264 } 2244 }
2265 2245
2266 2246
2267 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2247 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2268 Handle<Object> object, 2248 Handle<Object> object,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 __ ret(2 * kPointerSize); 2309 __ ret(2 * kPointerSize);
2330 2310
2331 // If the argument is negative, clear the sign, and return a new 2311 // If the argument is negative, clear the sign, and return a new
2332 // number. We still have the sign mask in rdi. 2312 // number. We still have the sign mask in rdi.
2333 __ bind(&negative_sign); 2313 __ bind(&negative_sign);
2334 __ xor_(rbx, rdi); 2314 __ xor_(rbx, rdi);
2335 __ AllocateHeapNumber(rax, rdx, &slow); 2315 __ AllocateHeapNumber(rax, rdx, &slow);
2336 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 2316 __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
2337 __ ret(2 * kPointerSize); 2317 __ ret(2 * kPointerSize);
2338 2318
2339 // Tail call the full function. We do not have to patch the receiver
2340 // because the function makes no use of it.
2341 __ bind(&slow); 2319 __ bind(&slow);
2342 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2320 // We do not have to patch the receiver because the function makes no use of
2343 ? CALL_AS_FUNCTION 2321 // it.
2344 : CALL_AS_METHOD; 2322 GenerateCallFunction(Handle<Object>::null(), function);
2345 ParameterCount expected(function);
2346 __ InvokeFunction(function, expected, arguments(),
2347 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2348 2323
2349 HandlerFrontendFooter(&miss); 2324 HandlerFrontendFooter(&miss);
2350 2325
2351 // Return the generated code. 2326 // Return the generated code.
2352 return GetCode(type, name); 2327 return GetCode(type, name);
2353 } 2328 }
2354 2329
2355 2330
2356 Handle<Code> CallStubCompiler::CompileFastApiCall( 2331 Handle<Code> CallStubCompiler::CompileFastApiCall(
2357 const CallOptimization& optimization, 2332 const CallOptimization& optimization,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2395 // Move the return address on top of the stack. 2370 // Move the return address on top of the stack.
2396 __ movq(rax, 2371 __ movq(rax,
2397 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2372 StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
2398 __ movq(StackOperandForReturnAddress(0), rax); 2373 __ movq(StackOperandForReturnAddress(0), rax);
2399 2374
2400 GenerateFastApiCall(masm(), optimization, argc); 2375 GenerateFastApiCall(masm(), optimization, argc);
2401 2376
2402 __ bind(&miss); 2377 __ bind(&miss);
2403 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2378 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2404 2379
2405 __ bind(&miss_before_stack_reserved); 2380 HandlerFrontendFooter(&miss_before_stack_reserved);
2406 GenerateMissBranch();
2407 2381
2408 // Return the generated code. 2382 // Return the generated code.
2409 return GetCode(function); 2383 return GetCode(function);
2410 } 2384 }
2411 2385
2412 2386
2413 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2387 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2414 Label success; 2388 Label success;
2415 // Check that the object is a boolean. 2389 // Check that the object is a boolean.
2416 __ CompareRoot(object, Heap::kTrueValueRootIndex); 2390 __ CompareRoot(object, Heap::kTrueValueRootIndex);
2417 __ j(equal, &success); 2391 __ j(equal, &success);
2418 __ CompareRoot(object, Heap::kFalseValueRootIndex); 2392 __ CompareRoot(object, Heap::kFalseValueRootIndex);
2419 __ j(not_equal, miss); 2393 __ j(not_equal, miss);
2420 __ bind(&success); 2394 __ bind(&success);
2421 } 2395 }
2422 2396
2423 2397
2424 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2398 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2425 if (object->IsGlobalObject()) { 2399 if (!object.is_null() && object->IsGlobalObject()) {
2426 StackArgumentsAccessor args(rsp, arguments()); 2400 StackArgumentsAccessor args(rsp, arguments());
2427 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2401 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2428 __ movq(args.GetReceiverOperand(), rdx); 2402 __ movq(args.GetReceiverOperand(), rdx);
2429 } 2403 }
2430 } 2404 }
2431 2405
2432 2406
2433 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2407 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2434 Handle<JSObject> holder, 2408 Handle<JSObject> holder,
2435 Handle<Name> name, 2409 Handle<Name> name,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2478 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2505 reg = CheckPrototypes( 2479 reg = CheckPrototypes(
2506 IC::CurrentTypeOf(prototype, isolate()), 2480 IC::CurrentTypeOf(prototype, isolate()),
2507 rax, holder, rbx, rdx, rdi, name, miss); 2481 rax, holder, rbx, rdx, rdi, name, miss);
2508 } 2482 }
2509 2483
2510 return reg; 2484 return reg;
2511 } 2485 }
2512 2486
2513 2487
2514 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2488 void CallStubCompiler::GenerateCallFunction(Handle<Object> object,
2515 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2489 Register function,
2516 ? CALL_AS_FUNCTION 2490 Label* miss) {
2517 : CALL_AS_METHOD; 2491 // Check that the function really is a function.
2518 ParameterCount expected(function); 2492 GenerateFunctionCheck(function, rbx, miss);
2519 __ InvokeFunction(function, expected, arguments(), 2493
2520 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2494 if (!function.is(rdi)) __ movq(rdi, function);
2495 PatchGlobalProxy(object);
2496
2497 // Invoke the function.
2498 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2499 NullCallWrapper(), call_kind());
2521 } 2500 }
2522 2501
2523 2502
2524 Handle<Code> CallStubCompiler::CompileCallConstant(
2525 Handle<Object> object,
2526 Handle<JSObject> holder,
2527 Handle<Name> name,
2528 CheckType check,
2529 Handle<JSFunction> function) {
2530 if (HasCustomCallGenerator(function)) {
2531 Handle<Code> code = CompileCustomCall(object, holder,
2532 Handle<PropertyCell>::null(),
2533 function, Handle<String>::cast(name),
2534 Code::FAST);
2535 // A null handle means bail out to the regular compiler code below.
2536 if (!code.is_null()) return code;
2537 }
2538
2539 Label miss;
2540 HandlerFrontendHeader(object, holder, name, check, &miss);
2541 PatchGlobalProxy(object);
2542 CompileHandlerBackend(function);
2543 HandlerFrontendFooter(&miss);
2544
2545 // Return the generated code.
2546 return GetCode(function);
2547 }
2548
2549
2550 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2503 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2551 Handle<JSObject> holder, 2504 Handle<JSObject> holder,
2552 Handle<Name> name) { 2505 Handle<Name> name) {
2553 Label miss; 2506 Label miss;
2554 GenerateNameCheck(name, &miss); 2507 GenerateNameCheck(name, &miss);
2555 2508
2556 LookupResult lookup(isolate()); 2509 LookupResult lookup(isolate());
2557 LookupPostInterceptor(holder, name, &lookup); 2510 LookupPostInterceptor(holder, name, &lookup);
2558 2511
2559 // Get the receiver from the stack. 2512 // Get the receiver from the stack.
2560 StackArgumentsAccessor args(rsp, arguments()); 2513 StackArgumentsAccessor args(rsp, arguments());
2561 __ movq(rdx, args.GetReceiverOperand()); 2514 __ movq(rdx, args.GetReceiverOperand());
2562 2515
2563 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); 2516 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
2564 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2517 compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
2565 &miss); 2518 &miss);
2566 2519
2567 // Restore receiver. 2520 // Restore receiver.
2568 __ movq(rdx, args.GetReceiverOperand()); 2521 __ movq(rdx, args.GetReceiverOperand());
2569 2522
2570 // Check that the function really is a function. 2523 GenerateCallFunction(object, rax, &miss);
2571 __ JumpIfSmi(rax, &miss);
2572 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2573 __ j(not_equal, &miss);
2574 2524
2575 // Patch the receiver on the stack with the global proxy if 2525 HandlerFrontendFooter(&miss);
2576 // necessary.
2577 if (object->IsGlobalObject()) {
2578 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2579 __ movq(args.GetReceiverOperand(), rdx);
2580 }
2581
2582 // Invoke the function.
2583 __ movq(rdi, rax);
2584 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2585 ? CALL_AS_FUNCTION
2586 : CALL_AS_METHOD;
2587 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2588 NullCallWrapper(), call_kind);
2589
2590 // Handle load cache miss.
2591 __ bind(&miss);
2592 GenerateMissBranch();
2593 2526
2594 // Return the generated code. 2527 // Return the generated code.
2595 return GetCode(Code::FAST, name); 2528 return GetCode(Code::FAST, name);
2596 } 2529 }
2597 2530
2598 2531
2599 Handle<Code> CallStubCompiler::CompileCallGlobal( 2532 Handle<Code> CallStubCompiler::CompileCallGlobal(
2600 Handle<JSObject> object, 2533 Handle<JSObject> object,
2601 Handle<GlobalObject> holder, 2534 Handle<GlobalObject> holder,
2602 Handle<PropertyCell> cell, 2535 Handle<PropertyCell> cell,
2603 Handle<JSFunction> function, 2536 Handle<JSFunction> function,
2604 Handle<Name> name) { 2537 Handle<Name> name) {
2605 if (HasCustomCallGenerator(function)) { 2538 if (HasCustomCallGenerator(function)) {
2606 Handle<Code> code = CompileCustomCall( 2539 Handle<Code> code = CompileCustomCall(
2607 object, holder, cell, function, Handle<String>::cast(name), 2540 object, holder, cell, function, Handle<String>::cast(name),
2608 Code::NORMAL); 2541 Code::NORMAL);
2609 // A null handle means bail out to the regular compiler code below. 2542 // A null handle means bail out to the regular compiler code below.
2610 if (!code.is_null()) return code; 2543 if (!code.is_null()) return code;
2611 } 2544 }
2612 2545
2613 Label miss; 2546 Label miss;
2614 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2547 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2548 // Potentially loads a closure that matches the shared function info of the
2549 // function, rather than function.
2615 GenerateLoadFunctionFromCell(cell, function, &miss); 2550 GenerateLoadFunctionFromCell(cell, function, &miss);
2616 PatchGlobalProxy(object);
2617
2618 // Set up the context (function already in rdi).
2619 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2620
2621 // Jump to the cached code (tail call).
2622 Counters* counters = isolate()->counters(); 2551 Counters* counters = isolate()->counters();
2623 __ IncrementCounter(counters->call_global_inline(), 1); 2552 __ IncrementCounter(counters->call_global_inline(), 1);
2624 ParameterCount expected(function->shared()->formal_parameter_count()); 2553 GenerateCallFunction(object, rdi, function);
2625 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2626 ? CALL_AS_FUNCTION
2627 : CALL_AS_METHOD;
2628 // We call indirectly through the code field in the function to
2629 // allow recompilation to take effect without changing any of the
2630 // call sites.
2631 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2632 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2633 NullCallWrapper(), call_kind);
2634
2635 HandlerFrontendFooter(&miss); 2554 HandlerFrontendFooter(&miss);
2636 2555
2637 // Return the generated code. 2556 // Return the generated code.
2638 return GetCode(Code::NORMAL, name); 2557 return GetCode(Code::NORMAL, name);
2639 } 2558 }
2640 2559
2641 2560
2642 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2561 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2643 Handle<JSObject> object, 2562 Handle<JSObject> object,
2644 Handle<JSObject> holder, 2563 Handle<JSObject> holder,
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 // ----------------------------------- 2928 // -----------------------------------
3010 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2929 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3011 } 2930 }
3012 2931
3013 2932
3014 #undef __ 2933 #undef __
3015 2934
3016 } } // namespace v8::internal 2935 } } // namespace v8::internal
3017 2936
3018 #endif // V8_TARGET_ARCH_X64 2937 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/macro-assembler-x64.cc ('K') | « src/x64/macro-assembler-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698