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

Side by Side Diff: src/ia32/stub-cache-ia32.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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 ApiParameterOperand(1), 638 ApiParameterOperand(1),
639 argc + kFastApiCallArguments + 1, 639 argc + kFastApiCallArguments + 1,
640 return_value_operand, 640 return_value_operand,
641 restore_context ? 641 restore_context ?
642 &context_restore_operand : NULL); 642 &context_restore_operand : NULL);
643 } 643 }
644 644
645 645
646 class CallInterceptorCompiler BASE_EMBEDDED { 646 class CallInterceptorCompiler BASE_EMBEDDED {
647 public: 647 public:
648 CallInterceptorCompiler(StubCompiler* stub_compiler, 648 CallInterceptorCompiler(CallStubCompiler* stub_compiler,
649 const ParameterCount& arguments, 649 const ParameterCount& arguments,
650 Register name, 650 Register name,
651 Code::ExtraICState extra_state) 651 Code::ExtraICState extra_state)
652 : stub_compiler_(stub_compiler), 652 : stub_compiler_(stub_compiler),
653 arguments_(arguments), 653 arguments_(arguments),
654 name_(name), 654 name_(name),
655 extra_state_(extra_state) {} 655 extra_state_(extra_state) {}
656 656
657 void Compile(MacroAssembler* masm, 657 void Compile(MacroAssembler* masm,
658 Handle<JSObject> object, 658 Handle<JSObject> object,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // for API (object which is instanceof for the signature). It's 749 // for API (object which is instanceof for the signature). It's
750 // safe to omit it here, as if present, it should be fetched 750 // safe to omit it here, as if present, it should be fetched
751 // by the previous CheckPrototypes. 751 // by the previous CheckPrototypes.
752 ASSERT(depth2 == kInvalidProtoDepth); 752 ASSERT(depth2 == kInvalidProtoDepth);
753 } 753 }
754 754
755 // Invoke function. 755 // Invoke function.
756 if (can_do_fast_api_call) { 756 if (can_do_fast_api_call) {
757 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 757 GenerateFastApiCall(masm, optimization, arguments_.immediate());
758 } else { 758 } else {
759 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 759 Handle<JSFunction> fun = optimization.constant_function();
760 ? CALL_AS_FUNCTION 760 stub_compiler_->GenerateCallFunction(object, fun);
761 : CALL_AS_METHOD;
762 Handle<JSFunction> function = optimization.constant_function();
763 ParameterCount expected(function);
764 __ InvokeFunction(function, expected, arguments_,
765 JUMP_FUNCTION, NullCallWrapper(), call_kind);
766 } 761 }
767 762
768 // Deferred code for fast API call case---clean preallocated space. 763 // Deferred code for fast API call case---clean preallocated space.
769 if (can_do_fast_api_call) { 764 if (can_do_fast_api_call) {
770 __ bind(&miss_cleanup); 765 __ bind(&miss_cleanup);
771 FreeSpaceForFastApiCall(masm, scratch1); 766 FreeSpaceForFastApiCall(masm, scratch1);
772 __ jmp(miss_label); 767 __ jmp(miss_label);
773 } 768 }
774 769
775 // Invoke a regular function. 770 // Invoke a regular function.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 823
829 __ pop(name_); // Restore the name. 824 __ pop(name_); // Restore the name.
830 __ pop(receiver); // Restore the holder. 825 __ pop(receiver); // Restore the holder.
831 // Leave the internal frame. 826 // Leave the internal frame.
832 } 827 }
833 828
834 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
835 __ j(not_equal, interceptor_succeeded); 830 __ j(not_equal, interceptor_succeeded);
836 } 831 }
837 832
838 StubCompiler* stub_compiler_; 833 CallStubCompiler* stub_compiler_;
839 const ParameterCount& arguments_; 834 const ParameterCount& arguments_;
840 Register name_; 835 Register name_;
841 Code::ExtraICState extra_state_; 836 Code::ExtraICState extra_state_;
842 }; 837 };
843 838
844 839
845 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
846 Label* label, 841 Label* label,
847 Handle<Name> name) { 842 Handle<Name> name) {
848 if (!label->is_unused()) { 843 if (!label->is_unused()) {
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 1597
1603 1598
1604 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1599 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1605 if (kind_ == Code::KEYED_CALL_IC) { 1600 if (kind_ == Code::KEYED_CALL_IC) {
1606 __ cmp(ecx, Immediate(name)); 1601 __ cmp(ecx, Immediate(name));
1607 __ j(not_equal, miss); 1602 __ j(not_equal, miss);
1608 } 1603 }
1609 } 1604 }
1610 1605
1611 1606
1607 void CallStubCompiler::GenerateFunctionCheck(Register function,
1608 Register scratch,
1609 Label* miss) {
1610 __ JumpIfSmi(function, miss);
1611 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1612 __ j(not_equal, miss);
1613 }
1614
1615
1612 void CallStubCompiler::GenerateLoadFunctionFromCell( 1616 void CallStubCompiler::GenerateLoadFunctionFromCell(
1613 Handle<Cell> cell, 1617 Handle<Cell> cell,
1614 Handle<JSFunction> function, 1618 Handle<JSFunction> function,
1615 Label* miss) { 1619 Label* miss) {
1616 // Get the value from the cell. 1620 // Get the value from the cell.
1617 if (Serializer::enabled()) { 1621 if (Serializer::enabled()) {
1618 __ mov(edi, Immediate(cell)); 1622 __ mov(edi, Immediate(cell));
1619 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); 1623 __ mov(edi, FieldOperand(edi, Cell::kValueOffset));
1620 } else { 1624 } else {
1621 __ mov(edi, Operand::ForCell(cell)); 1625 __ mov(edi, Operand::ForCell(cell));
1622 } 1626 }
1623 1627
1624 // Check that the cell contains the same function. 1628 // Check that the cell contains the same function.
1625 if (isolate()->heap()->InNewSpace(*function)) { 1629 if (isolate()->heap()->InNewSpace(*function)) {
1626 // We can't embed a pointer to a function in new space so we have 1630 // We can't embed a pointer to a function in new space so we have
1627 // to verify that the shared function info is unchanged. This has 1631 // to verify that the shared function info is unchanged. This has
1628 // the nice side effect that multiple closures based on the same 1632 // the nice side effect that multiple closures based on the same
1629 // function can all use this call IC. Before we load through the 1633 // function can all use this call IC. Before we load through the
1630 // function, we have to verify that it still is a function. 1634 // function, we have to verify that it still is a function.
1631 __ JumpIfSmi(edi, miss); 1635 GenerateFunctionCheck(edi, ebx, miss);
1632 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1633 __ j(not_equal, miss);
1634 1636
1635 // Check the shared function info. Make sure it hasn't changed. 1637 // Check the shared function info. Make sure it hasn't changed.
1636 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1638 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1637 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1639 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1638 } else { 1640 } else {
1639 __ cmp(edi, Immediate(function)); 1641 __ cmp(edi, Immediate(function));
1640 } 1642 }
1641 __ j(not_equal, miss); 1643 __ j(not_equal, miss);
1642 } 1644 }
1643 1645
(...skipping 12 matching lines...) Expand all
1656 PropertyIndex index, 1658 PropertyIndex index,
1657 Handle<Name> name) { 1659 Handle<Name> name) {
1658 Label miss; 1660 Label miss;
1659 1661
1660 Register reg = HandlerFrontendHeader( 1662 Register reg = HandlerFrontendHeader(
1661 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1663 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1662 1664
1663 GenerateFastPropertyLoad( 1665 GenerateFastPropertyLoad(
1664 masm(), edi, reg, index.is_inobject(holder), 1666 masm(), edi, reg, index.is_inobject(holder),
1665 index.translate(holder), Representation::Tagged()); 1667 index.translate(holder), Representation::Tagged());
1666 1668 GenerateCallFunction(object, edi, &miss);
1667 // Check that the function really is a function.
1668 __ JumpIfSmi(edi, &miss);
1669 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1670 __ j(not_equal, &miss);
1671
1672 PatchGlobalProxy(object);
1673
1674 // Invoke the function.
1675 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1676 ? CALL_AS_FUNCTION
1677 : CALL_AS_METHOD;
1678 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1679 NullCallWrapper(), call_kind);
1680 1669
1681 HandlerFrontendFooter(&miss); 1670 HandlerFrontendFooter(&miss);
1682 1671
1683 // Return the generated code. 1672 // Return the generated code.
1684 return GetCode(Code::FAST, name); 1673 return GetCode(Code::FAST, name);
1685 } 1674 }
1686 1675
1687 1676
1688 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1677 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1689 Handle<Object> object, 1678 Handle<Object> object,
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 2070
2082 if (index_out_of_range.is_linked()) { 2071 if (index_out_of_range.is_linked()) {
2083 __ bind(&index_out_of_range); 2072 __ bind(&index_out_of_range);
2084 __ Set(eax, Immediate(factory()->nan_value())); 2073 __ Set(eax, Immediate(factory()->nan_value()));
2085 __ ret((argc + 1) * kPointerSize); 2074 __ ret((argc + 1) * kPointerSize);
2086 } 2075 }
2087 2076
2088 __ bind(&miss); 2077 __ bind(&miss);
2089 // Restore function name in ecx. 2078 // Restore function name in ecx.
2090 __ Set(ecx, Immediate(name)); 2079 __ Set(ecx, Immediate(name));
2091 __ bind(&name_miss); 2080 HandlerFrontendFooter(&name_miss);
2092 GenerateMissBranch();
2093 2081
2094 // Return the generated code. 2082 // Return the generated code.
2095 return GetCode(type, name); 2083 return GetCode(type, name);
2096 } 2084 }
2097 2085
2098 2086
2099 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2087 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2100 Handle<Object> object, 2088 Handle<Object> object,
2101 Handle<JSObject> holder, 2089 Handle<JSObject> holder,
2102 Handle<Cell> cell, 2090 Handle<Cell> cell,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2150 2138
2151 if (index_out_of_range.is_linked()) { 2139 if (index_out_of_range.is_linked()) {
2152 __ bind(&index_out_of_range); 2140 __ bind(&index_out_of_range);
2153 __ Set(eax, Immediate(factory()->empty_string())); 2141 __ Set(eax, Immediate(factory()->empty_string()));
2154 __ ret((argc + 1) * kPointerSize); 2142 __ ret((argc + 1) * kPointerSize);
2155 } 2143 }
2156 2144
2157 __ bind(&miss); 2145 __ bind(&miss);
2158 // Restore function name in ecx. 2146 // Restore function name in ecx.
2159 __ Set(ecx, Immediate(name)); 2147 __ Set(ecx, Immediate(name));
2160 __ bind(&name_miss); 2148 HandlerFrontendFooter(&name_miss);
2161 GenerateMissBranch();
2162 2149
2163 // Return the generated code. 2150 // Return the generated code.
2164 return GetCode(type, name); 2151 return GetCode(type, name);
2165 } 2152 }
2166 2153
2167 2154
2168 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2155 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2169 Handle<Object> object, 2156 Handle<Object> object,
2170 Handle<JSObject> holder, 2157 Handle<JSObject> holder,
2171 Handle<Cell> cell, 2158 Handle<Cell> cell,
(...skipping 28 matching lines...) Expand all
2200 // Convert the smi code to uint16. 2187 // Convert the smi code to uint16.
2201 __ and_(code, Immediate(Smi::FromInt(0xffff))); 2188 __ and_(code, Immediate(Smi::FromInt(0xffff)));
2202 2189
2203 StringCharFromCodeGenerator generator(code, eax); 2190 StringCharFromCodeGenerator generator(code, eax);
2204 generator.GenerateFast(masm()); 2191 generator.GenerateFast(masm());
2205 __ ret(2 * kPointerSize); 2192 __ ret(2 * kPointerSize);
2206 2193
2207 StubRuntimeCallHelper call_helper; 2194 StubRuntimeCallHelper call_helper;
2208 generator.GenerateSlow(masm(), call_helper); 2195 generator.GenerateSlow(masm(), call_helper);
2209 2196
2210 // Tail call the full function. We do not have to patch the receiver
2211 // because the function makes no use of it.
2212 __ bind(&slow); 2197 __ bind(&slow);
2213 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2198 // We do not have to patch the receiver because the function makes no use of
2214 ? CALL_AS_FUNCTION 2199 // it.
2215 : CALL_AS_METHOD; 2200 GenerateCallFunction(Handle<Object>::null(), function);
2216 ParameterCount expected(function);
2217 __ InvokeFunction(function, expected, arguments(),
2218 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2219 2201
2220 HandlerFrontendFooter(&miss); 2202 HandlerFrontendFooter(&miss);
2221 2203
2222 // Return the generated code. 2204 // Return the generated code.
2223 return GetCode(type, name); 2205 return GetCode(type, name);
2224 } 2206 }
2225 2207
2226 2208
2227 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2209 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2228 Handle<Object> object, 2210 Handle<Object> object,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 // Return a new heap number. 2297 // Return a new heap number.
2316 __ AllocateHeapNumber(eax, ebx, edx, &slow); 2298 __ AllocateHeapNumber(eax, ebx, edx, &slow);
2317 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 2299 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
2318 __ ret(2 * kPointerSize); 2300 __ ret(2 * kPointerSize);
2319 2301
2320 // Return the argument (when it's an already round heap number). 2302 // Return the argument (when it's an already round heap number).
2321 __ bind(&already_round); 2303 __ bind(&already_round);
2322 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2304 __ mov(eax, Operand(esp, 1 * kPointerSize));
2323 __ ret(2 * kPointerSize); 2305 __ ret(2 * kPointerSize);
2324 2306
2325 // Tail call the full function. We do not have to patch the receiver
2326 // because the function makes no use of it.
2327 __ bind(&slow); 2307 __ bind(&slow);
2328 ParameterCount expected(function); 2308 // We do not have to patch the receiver because the function makes no use of
2329 __ InvokeFunction(function, expected, arguments(), 2309 // it.
2330 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2310 GenerateCallFunction(Handle<Object>::null(), function);
2331 2311
2332 HandlerFrontendFooter(&miss); 2312 HandlerFrontendFooter(&miss);
2333 2313
2334 // Return the generated code. 2314 // Return the generated code.
2335 return GetCode(type, name); 2315 return GetCode(type, name);
2336 } 2316 }
2337 2317
2338 2318
2339 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2319 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2340 Handle<Object> object, 2320 Handle<Object> object,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 // If the argument is negative, clear the sign, and return a new 2384 // If the argument is negative, clear the sign, and return a new
2405 // number. 2385 // number.
2406 __ bind(&negative_sign); 2386 __ bind(&negative_sign);
2407 __ and_(ebx, ~HeapNumber::kSignMask); 2387 __ and_(ebx, ~HeapNumber::kSignMask);
2408 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); 2388 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset));
2409 __ AllocateHeapNumber(eax, edi, edx, &slow); 2389 __ AllocateHeapNumber(eax, edi, edx, &slow);
2410 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); 2390 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
2411 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); 2391 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2412 __ ret(2 * kPointerSize); 2392 __ ret(2 * kPointerSize);
2413 2393
2414 // Tail call the full function. We do not have to patch the receiver
2415 // because the function makes no use of it.
2416 __ bind(&slow); 2394 __ bind(&slow);
2417 ParameterCount expected(function); 2395 // We do not have to patch the receiver because the function makes no use of
2418 __ InvokeFunction(function, expected, arguments(), 2396 // it.
2419 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2397 GenerateCallFunction(Handle<Object>::null(), function);
2420 2398
2421 HandlerFrontendFooter(&miss); 2399 HandlerFrontendFooter(&miss);
2422 2400
2423 // Return the generated code. 2401 // Return the generated code.
2424 return GetCode(type, name); 2402 return GetCode(type, name);
2425 } 2403 }
2426 2404
2427 2405
2428 Handle<Code> CallStubCompiler::CompileFastApiCall( 2406 Handle<Code> CallStubCompiler::CompileFastApiCall(
2429 const CallOptimization& optimization, 2407 const CallOptimization& optimization,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); 2447 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
2470 __ mov(Operand(esp, 0 * kPointerSize), eax); 2448 __ mov(Operand(esp, 0 * kPointerSize), eax);
2471 2449
2472 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2450 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2473 // duplicate of return address and will be overwritten. 2451 // duplicate of return address and will be overwritten.
2474 GenerateFastApiCall(masm(), optimization, argc); 2452 GenerateFastApiCall(masm(), optimization, argc);
2475 2453
2476 __ bind(&miss); 2454 __ bind(&miss);
2477 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2455 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2478 2456
2479 __ bind(&miss_before_stack_reserved); 2457 HandlerFrontendFooter(&miss_before_stack_reserved);
2480 GenerateMissBranch();
2481 2458
2482 // Return the generated code. 2459 // Return the generated code.
2483 return GetCode(function); 2460 return GetCode(function);
2484 } 2461 }
2485 2462
2486 2463
2487 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2464 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2488 Label success; 2465 Label success;
2489 // Check that the object is a boolean. 2466 // Check that the object is a boolean.
2490 __ cmp(object, factory()->true_value()); 2467 __ cmp(object, factory()->true_value());
2491 __ j(equal, &success); 2468 __ j(equal, &success);
2492 __ cmp(object, factory()->false_value()); 2469 __ cmp(object, factory()->false_value());
2493 __ j(not_equal, miss); 2470 __ j(not_equal, miss);
2494 __ bind(&success); 2471 __ bind(&success);
2495 } 2472 }
2496 2473
2497 2474
2498 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2475 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2499 if (object->IsGlobalObject()) { 2476 if (!object.is_null() && object->IsGlobalObject()) {
2500 const int argc = arguments().immediate(); 2477 const int argc = arguments().immediate();
2501 const int receiver_offset = (argc + 1) * kPointerSize; 2478 const int receiver_offset = (argc + 1) * kPointerSize;
2502 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2479 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2503 __ mov(Operand(esp, receiver_offset), edx); 2480 __ mov(Operand(esp, receiver_offset), edx);
2504 } 2481 }
2505 } 2482 }
2506 2483
2507 2484
2508 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2485 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2509 Handle<JSObject> holder, 2486 Handle<JSObject> holder,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2579 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2556 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2580 reg = CheckPrototypes( 2557 reg = CheckPrototypes(
2581 IC::CurrentTypeOf(prototype, isolate()), 2558 IC::CurrentTypeOf(prototype, isolate()),
2582 eax, holder, ebx, edx, edi, name, miss); 2559 eax, holder, ebx, edx, edi, name, miss);
2583 } 2560 }
2584 2561
2585 return reg; 2562 return reg;
2586 } 2563 }
2587 2564
2588 2565
2589 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2566 void CallStubCompiler::GenerateCallFunction(Handle<Object> object,
2590 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2567 Register function,
2591 ? CALL_AS_FUNCTION 2568 Label* miss) {
2592 : CALL_AS_METHOD; 2569 // Check that the function really is a function.
2593 ParameterCount expected(function); 2570 GenerateFunctionCheck(function, ebx, miss);
2594 __ InvokeFunction(function, expected, arguments(), 2571
2595 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2572 if (!function.is(edi)) __ mov(edi, function);
2573 PatchGlobalProxy(object);
2574
2575 // Invoke the function.
2576 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2577 NullCallWrapper(), call_kind());
2596 } 2578 }
2597 2579
2598 2580
2599 Handle<Code> CallStubCompiler::CompileCallConstant(
2600 Handle<Object> object,
2601 Handle<JSObject> holder,
2602 Handle<Name> name,
2603 CheckType check,
2604 Handle<JSFunction> function) {
2605
2606 if (HasCustomCallGenerator(function)) {
2607 Handle<Code> code = CompileCustomCall(object, holder,
2608 Handle<Cell>::null(),
2609 function, Handle<String>::cast(name),
2610 Code::FAST);
2611 // A null handle means bail out to the regular compiler code below.
2612 if (!code.is_null()) return code;
2613 }
2614
2615 Label miss;
2616 HandlerFrontendHeader(object, holder, name, check, &miss);
2617 PatchGlobalProxy(object);
2618 CompileHandlerBackend(function);
2619 HandlerFrontendFooter(&miss);
2620
2621 // Return the generated code.
2622 return GetCode(function);
2623 }
2624
2625
2626 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2581 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2627 Handle<JSObject> holder, 2582 Handle<JSObject> holder,
2628 Handle<Name> name) { 2583 Handle<Name> name) {
2629 Label miss; 2584 Label miss;
2630 2585
2631 GenerateNameCheck(name, &miss); 2586 GenerateNameCheck(name, &miss);
2632 2587
2633 // Get the number of arguments. 2588 // Get the number of arguments.
2634 const int argc = arguments().immediate(); 2589 const int argc = arguments().immediate();
2635 2590
2636 LookupResult lookup(isolate()); 2591 LookupResult lookup(isolate());
2637 LookupPostInterceptor(holder, name, &lookup); 2592 LookupPostInterceptor(holder, name, &lookup);
2638 2593
2639 // Get the receiver from the stack. 2594 // Get the receiver from the stack.
2640 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2595 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2641 2596
2642 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); 2597 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_);
2643 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, 2598 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
2644 &miss); 2599 &miss);
2645 2600
2646 // Restore receiver. 2601 // Restore receiver.
2647 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2602 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2648 2603
2649 // Check that the function really is a function. 2604 GenerateCallFunction(object, eax, &miss);
2650 __ JumpIfSmi(eax, &miss);
2651 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2652 __ j(not_equal, &miss);
2653 2605
2654 // Patch the receiver on the stack with the global proxy if 2606 HandlerFrontendFooter(&miss);
2655 // necessary.
2656 if (object->IsGlobalObject()) {
2657 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2658 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2659 }
2660
2661 // Invoke the function.
2662 __ mov(edi, eax);
2663 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2664 ? CALL_AS_FUNCTION
2665 : CALL_AS_METHOD;
2666 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2667 NullCallWrapper(), call_kind);
2668
2669 // Handle load cache miss.
2670 __ bind(&miss);
2671 GenerateMissBranch();
2672 2607
2673 // Return the generated code. 2608 // Return the generated code.
2674 return GetCode(Code::FAST, name); 2609 return GetCode(Code::FAST, name);
2675 } 2610 }
2676 2611
2677 2612
2678 Handle<Code> CallStubCompiler::CompileCallGlobal( 2613 Handle<Code> CallStubCompiler::CompileCallGlobal(
2679 Handle<JSObject> object, 2614 Handle<JSObject> object,
2680 Handle<GlobalObject> holder, 2615 Handle<GlobalObject> holder,
2681 Handle<PropertyCell> cell, 2616 Handle<PropertyCell> cell,
2682 Handle<JSFunction> function, 2617 Handle<JSFunction> function,
2683 Handle<Name> name) { 2618 Handle<Name> name) {
2684 if (HasCustomCallGenerator(function)) { 2619 if (HasCustomCallGenerator(function)) {
2685 Handle<Code> code = CompileCustomCall( 2620 Handle<Code> code = CompileCustomCall(
2686 object, holder, cell, function, Handle<String>::cast(name), 2621 object, holder, cell, function, Handle<String>::cast(name),
2687 Code::NORMAL); 2622 Code::NORMAL);
2688 // A null handle means bail out to the regular compiler code below. 2623 // A null handle means bail out to the regular compiler code below.
2689 if (!code.is_null()) return code; 2624 if (!code.is_null()) return code;
2690 } 2625 }
2691 2626
2692 Label miss; 2627 Label miss;
2693 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2628 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2629 // Potentially loads a closure that matches the shared function info of the
2630 // function, rather than function.
2694 GenerateLoadFunctionFromCell(cell, function, &miss); 2631 GenerateLoadFunctionFromCell(cell, function, &miss);
2695 PatchGlobalProxy(object); 2632 GenerateCallFunction(object, edi, function);
2696
2697 // Set up the context (function already in edi).
2698 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2699
2700 // Jump to the cached code (tail call).
2701 Counters* counters = isolate()->counters();
2702 __ IncrementCounter(counters->call_global_inline(), 1);
2703 ParameterCount expected(function->shared()->formal_parameter_count());
2704 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2705 ? CALL_AS_FUNCTION
2706 : CALL_AS_METHOD;
2707 // We call indirectly through the code field in the function to
2708 // allow recompilation to take effect without changing any of the
2709 // call sites.
2710 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2711 expected, arguments(), JUMP_FUNCTION,
2712 NullCallWrapper(), call_kind);
2713 2633
2714 HandlerFrontendFooter(&miss); 2634 HandlerFrontendFooter(&miss);
2715 2635
2716 // Return the generated code. 2636 // Return the generated code.
2717 return GetCode(Code::NORMAL, name); 2637 return GetCode(Code::NORMAL, name);
2718 } 2638 }
2719 2639
2720 2640
2721 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2641 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2722 Handle<JSObject> object, 2642 Handle<JSObject> object,
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 // ----------------------------------- 2998 // -----------------------------------
3079 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 2999 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3080 } 3000 }
3081 3001
3082 3002
3083 #undef __ 3003 #undef __
3084 3004
3085 } } // namespace v8::internal 3005 } } // namespace v8::internal
3086 3006
3087 #endif // V8_TARGET_ARCH_IA32 3007 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698