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

Side by Side Diff: src/ia32/stub-cache-ia32.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/ia32/macro-assembler-ia32.cc ('k') | src/stub-cache.h » ('j') | 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 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(CallStubCompiler* stub_compiler, 648 CallInterceptorCompiler(StubCompiler* stub_compiler,
649 const ParameterCount& arguments, 649 const ParameterCount& arguments,
650 Register name, 650 Register name,
651 ExtraICState extra_state) 651 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 Handle<JSFunction> fun = optimization.constant_function(); 759 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
760 stub_compiler_->GenerateJumpFunction(object, fun); 760 ? CALL_AS_FUNCTION
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);
761 } 766 }
762 767
763 // Deferred code for fast API call case---clean preallocated space. 768 // Deferred code for fast API call case---clean preallocated space.
764 if (can_do_fast_api_call) { 769 if (can_do_fast_api_call) {
765 __ bind(&miss_cleanup); 770 __ bind(&miss_cleanup);
766 FreeSpaceForFastApiCall(masm, scratch1); 771 FreeSpaceForFastApiCall(masm, scratch1);
767 __ jmp(miss_label); 772 __ jmp(miss_label);
768 } 773 }
769 774
770 // Invoke a regular function. 775 // Invoke a regular function.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 823
819 __ pop(name_); // Restore the name. 824 __ pop(name_); // Restore the name.
820 __ pop(receiver); // Restore the holder. 825 __ pop(receiver); // Restore the holder.
821 // Leave the internal frame. 826 // Leave the internal frame.
822 } 827 }
823 828
824 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); 829 __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel());
825 __ j(not_equal, interceptor_succeeded); 830 __ j(not_equal, interceptor_succeeded);
826 } 831 }
827 832
828 CallStubCompiler* stub_compiler_; 833 StubCompiler* stub_compiler_;
829 const ParameterCount& arguments_; 834 const ParameterCount& arguments_;
830 Register name_; 835 Register name_;
831 ExtraICState extra_state_; 836 ExtraICState extra_state_;
832 }; 837 };
833 838
834 839
835 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
836 Label* label, 841 Label* label,
837 Handle<Name> name) { 842 Handle<Name> name) {
838 if (!label->is_unused()) { 843 if (!label->is_unused()) {
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 1595
1591 1596
1592 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1597 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
1593 if (kind_ == Code::KEYED_CALL_IC) { 1598 if (kind_ == Code::KEYED_CALL_IC) {
1594 __ cmp(ecx, Immediate(name)); 1599 __ cmp(ecx, Immediate(name));
1595 __ j(not_equal, miss); 1600 __ j(not_equal, miss);
1596 } 1601 }
1597 } 1602 }
1598 1603
1599 1604
1600 void CallStubCompiler::GenerateFunctionCheck(Register function,
1601 Register scratch,
1602 Label* miss) {
1603 __ JumpIfSmi(function, miss);
1604 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch);
1605 __ j(not_equal, miss);
1606 }
1607
1608
1609 void CallStubCompiler::GenerateLoadFunctionFromCell( 1605 void CallStubCompiler::GenerateLoadFunctionFromCell(
1610 Handle<Cell> cell, 1606 Handle<Cell> cell,
1611 Handle<JSFunction> function, 1607 Handle<JSFunction> function,
1612 Label* miss) { 1608 Label* miss) {
1613 // Get the value from the cell. 1609 // Get the value from the cell.
1614 if (Serializer::enabled()) { 1610 if (Serializer::enabled()) {
1615 __ mov(edi, Immediate(cell)); 1611 __ mov(edi, Immediate(cell));
1616 __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); 1612 __ mov(edi, FieldOperand(edi, Cell::kValueOffset));
1617 } else { 1613 } else {
1618 __ mov(edi, Operand::ForCell(cell)); 1614 __ mov(edi, Operand::ForCell(cell));
1619 } 1615 }
1620 1616
1621 // Check that the cell contains the same function. 1617 // Check that the cell contains the same function.
1622 if (isolate()->heap()->InNewSpace(*function)) { 1618 if (isolate()->heap()->InNewSpace(*function)) {
1623 // We can't embed a pointer to a function in new space so we have 1619 // We can't embed a pointer to a function in new space so we have
1624 // to verify that the shared function info is unchanged. This has 1620 // to verify that the shared function info is unchanged. This has
1625 // the nice side effect that multiple closures based on the same 1621 // the nice side effect that multiple closures based on the same
1626 // function can all use this call IC. Before we load through the 1622 // function can all use this call IC. Before we load through the
1627 // function, we have to verify that it still is a function. 1623 // function, we have to verify that it still is a function.
1628 GenerateFunctionCheck(edi, ebx, miss); 1624 __ JumpIfSmi(edi, miss);
1625 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1626 __ j(not_equal, miss);
1629 1627
1630 // Check the shared function info. Make sure it hasn't changed. 1628 // Check the shared function info. Make sure it hasn't changed.
1631 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1629 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1632 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1630 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1633 } else { 1631 } else {
1634 __ cmp(edi, Immediate(function)); 1632 __ cmp(edi, Immediate(function));
1635 } 1633 }
1636 __ j(not_equal, miss); 1634 __ j(not_equal, miss);
1637 } 1635 }
1638 1636
(...skipping 12 matching lines...) Expand all
1651 PropertyIndex index, 1649 PropertyIndex index,
1652 Handle<Name> name) { 1650 Handle<Name> name) {
1653 Label miss; 1651 Label miss;
1654 1652
1655 Register reg = HandlerFrontendHeader( 1653 Register reg = HandlerFrontendHeader(
1656 object, holder, name, RECEIVER_MAP_CHECK, &miss); 1654 object, holder, name, RECEIVER_MAP_CHECK, &miss);
1657 1655
1658 GenerateFastPropertyLoad( 1656 GenerateFastPropertyLoad(
1659 masm(), edi, reg, index.is_inobject(holder), 1657 masm(), edi, reg, index.is_inobject(holder),
1660 index.translate(holder), Representation::Tagged()); 1658 index.translate(holder), Representation::Tagged());
1661 GenerateJumpFunction(object, edi, &miss); 1659
1660 // Check that the function really is a function.
1661 __ JumpIfSmi(edi, &miss);
1662 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1663 __ j(not_equal, &miss);
1664
1665 PatchGlobalProxy(object);
1666
1667 // Invoke the function.
1668 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
1669 ? CALL_AS_FUNCTION
1670 : CALL_AS_METHOD;
1671 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1672 NullCallWrapper(), call_kind);
1662 1673
1663 HandlerFrontendFooter(&miss); 1674 HandlerFrontendFooter(&miss);
1664 1675
1665 // Return the generated code. 1676 // Return the generated code.
1666 return GetCode(Code::FAST, name); 1677 return GetCode(Code::FAST, name);
1667 } 1678 }
1668 1679
1669 1680
1670 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1681 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1671 Handle<Object> object, 1682 Handle<Object> object,
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2063 2074
2064 if (index_out_of_range.is_linked()) { 2075 if (index_out_of_range.is_linked()) {
2065 __ bind(&index_out_of_range); 2076 __ bind(&index_out_of_range);
2066 __ Set(eax, Immediate(factory()->nan_value())); 2077 __ Set(eax, Immediate(factory()->nan_value()));
2067 __ ret((argc + 1) * kPointerSize); 2078 __ ret((argc + 1) * kPointerSize);
2068 } 2079 }
2069 2080
2070 __ bind(&miss); 2081 __ bind(&miss);
2071 // Restore function name in ecx. 2082 // Restore function name in ecx.
2072 __ Set(ecx, Immediate(name)); 2083 __ Set(ecx, Immediate(name));
2073 HandlerFrontendFooter(&name_miss); 2084 __ bind(&name_miss);
2085 GenerateMissBranch();
2074 2086
2075 // Return the generated code. 2087 // Return the generated code.
2076 return GetCode(type, name); 2088 return GetCode(type, name);
2077 } 2089 }
2078 2090
2079 2091
2080 Handle<Code> CallStubCompiler::CompileStringCharAtCall( 2092 Handle<Code> CallStubCompiler::CompileStringCharAtCall(
2081 Handle<Object> object, 2093 Handle<Object> object,
2082 Handle<JSObject> holder, 2094 Handle<JSObject> holder,
2083 Handle<Cell> cell, 2095 Handle<Cell> cell,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 2143
2132 if (index_out_of_range.is_linked()) { 2144 if (index_out_of_range.is_linked()) {
2133 __ bind(&index_out_of_range); 2145 __ bind(&index_out_of_range);
2134 __ Set(eax, Immediate(factory()->empty_string())); 2146 __ Set(eax, Immediate(factory()->empty_string()));
2135 __ ret((argc + 1) * kPointerSize); 2147 __ ret((argc + 1) * kPointerSize);
2136 } 2148 }
2137 2149
2138 __ bind(&miss); 2150 __ bind(&miss);
2139 // Restore function name in ecx. 2151 // Restore function name in ecx.
2140 __ Set(ecx, Immediate(name)); 2152 __ Set(ecx, Immediate(name));
2141 HandlerFrontendFooter(&name_miss); 2153 __ bind(&name_miss);
2154 GenerateMissBranch();
2142 2155
2143 // Return the generated code. 2156 // Return the generated code.
2144 return GetCode(type, name); 2157 return GetCode(type, name);
2145 } 2158 }
2146 2159
2147 2160
2148 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2161 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
2149 Handle<Object> object, 2162 Handle<Object> object,
2150 Handle<JSObject> holder, 2163 Handle<JSObject> holder,
2151 Handle<Cell> cell, 2164 Handle<Cell> cell,
(...skipping 28 matching lines...) Expand all
2180 // Convert the smi code to uint16. 2193 // Convert the smi code to uint16.
2181 __ and_(code, Immediate(Smi::FromInt(0xffff))); 2194 __ and_(code, Immediate(Smi::FromInt(0xffff)));
2182 2195
2183 StringCharFromCodeGenerator generator(code, eax); 2196 StringCharFromCodeGenerator generator(code, eax);
2184 generator.GenerateFast(masm()); 2197 generator.GenerateFast(masm());
2185 __ ret(2 * kPointerSize); 2198 __ ret(2 * kPointerSize);
2186 2199
2187 StubRuntimeCallHelper call_helper; 2200 StubRuntimeCallHelper call_helper;
2188 generator.GenerateSlow(masm(), call_helper); 2201 generator.GenerateSlow(masm(), call_helper);
2189 2202
2203 // Tail call the full function. We do not have to patch the receiver
2204 // because the function makes no use of it.
2190 __ bind(&slow); 2205 __ bind(&slow);
2191 // We do not have to patch the receiver because the function makes no use of 2206 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2192 // it. 2207 ? CALL_AS_FUNCTION
2193 GenerateJumpFunctionIgnoreReceiver(function); 2208 : CALL_AS_METHOD;
2209 ParameterCount expected(function);
2210 __ InvokeFunction(function, expected, arguments(),
2211 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2194 2212
2195 HandlerFrontendFooter(&miss); 2213 HandlerFrontendFooter(&miss);
2196 2214
2197 // Return the generated code. 2215 // Return the generated code.
2198 return GetCode(type, name); 2216 return GetCode(type, name);
2199 } 2217 }
2200 2218
2201 2219
2202 Handle<Code> CallStubCompiler::CompileMathFloorCall( 2220 Handle<Code> CallStubCompiler::CompileMathFloorCall(
2203 Handle<Object> object, 2221 Handle<Object> object,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 // Return a new heap number. 2308 // Return a new heap number.
2291 __ AllocateHeapNumber(eax, ebx, edx, &slow); 2309 __ AllocateHeapNumber(eax, ebx, edx, &slow);
2292 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 2310 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
2293 __ ret(2 * kPointerSize); 2311 __ ret(2 * kPointerSize);
2294 2312
2295 // Return the argument (when it's an already round heap number). 2313 // Return the argument (when it's an already round heap number).
2296 __ bind(&already_round); 2314 __ bind(&already_round);
2297 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2315 __ mov(eax, Operand(esp, 1 * kPointerSize));
2298 __ ret(2 * kPointerSize); 2316 __ ret(2 * kPointerSize);
2299 2317
2318 // Tail call the full function. We do not have to patch the receiver
2319 // because the function makes no use of it.
2300 __ bind(&slow); 2320 __ bind(&slow);
2301 // We do not have to patch the receiver because the function makes no use of 2321 ParameterCount expected(function);
2302 // it. 2322 __ InvokeFunction(function, expected, arguments(),
2303 GenerateJumpFunctionIgnoreReceiver(function); 2323 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2304 2324
2305 HandlerFrontendFooter(&miss); 2325 HandlerFrontendFooter(&miss);
2306 2326
2307 // Return the generated code. 2327 // Return the generated code.
2308 return GetCode(type, name); 2328 return GetCode(type, name);
2309 } 2329 }
2310 2330
2311 2331
2312 Handle<Code> CallStubCompiler::CompileMathAbsCall( 2332 Handle<Code> CallStubCompiler::CompileMathAbsCall(
2313 Handle<Object> object, 2333 Handle<Object> object,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 // If the argument is negative, clear the sign, and return a new 2397 // If the argument is negative, clear the sign, and return a new
2378 // number. 2398 // number.
2379 __ bind(&negative_sign); 2399 __ bind(&negative_sign);
2380 __ and_(ebx, ~HeapNumber::kSignMask); 2400 __ and_(ebx, ~HeapNumber::kSignMask);
2381 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); 2401 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset));
2382 __ AllocateHeapNumber(eax, edi, edx, &slow); 2402 __ AllocateHeapNumber(eax, edi, edx, &slow);
2383 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); 2403 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
2384 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); 2404 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
2385 __ ret(2 * kPointerSize); 2405 __ ret(2 * kPointerSize);
2386 2406
2407 // Tail call the full function. We do not have to patch the receiver
2408 // because the function makes no use of it.
2387 __ bind(&slow); 2409 __ bind(&slow);
2388 // We do not have to patch the receiver because the function makes no use of 2410 ParameterCount expected(function);
2389 // it. 2411 __ InvokeFunction(function, expected, arguments(),
2390 GenerateJumpFunctionIgnoreReceiver(function); 2412 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
2391 2413
2392 HandlerFrontendFooter(&miss); 2414 HandlerFrontendFooter(&miss);
2393 2415
2394 // Return the generated code. 2416 // Return the generated code.
2395 return GetCode(type, name); 2417 return GetCode(type, name);
2396 } 2418 }
2397 2419
2398 2420
2399 Handle<Code> CallStubCompiler::CompileFastApiCall( 2421 Handle<Code> CallStubCompiler::CompileFastApiCall(
2400 const CallOptimization& optimization, 2422 const CallOptimization& optimization,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2440 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); 2462 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
2441 __ mov(Operand(esp, 0 * kPointerSize), eax); 2463 __ mov(Operand(esp, 0 * kPointerSize), eax);
2442 2464
2443 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2465 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2444 // duplicate of return address and will be overwritten. 2466 // duplicate of return address and will be overwritten.
2445 GenerateFastApiCall(masm(), optimization, argc); 2467 GenerateFastApiCall(masm(), optimization, argc);
2446 2468
2447 __ bind(&miss); 2469 __ bind(&miss);
2448 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2470 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2449 2471
2450 HandlerFrontendFooter(&miss_before_stack_reserved); 2472 __ bind(&miss_before_stack_reserved);
2473 GenerateMissBranch();
2451 2474
2452 // Return the generated code. 2475 // Return the generated code.
2453 return GetCode(function); 2476 return GetCode(function);
2454 } 2477 }
2455 2478
2456 2479
2457 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2480 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2458 Label success; 2481 Label success;
2459 // Check that the object is a boolean. 2482 // Check that the object is a boolean.
2460 __ cmp(object, factory()->true_value()); 2483 __ cmp(object, factory()->true_value());
2461 __ j(equal, &success); 2484 __ j(equal, &success);
2462 __ cmp(object, factory()->false_value()); 2485 __ cmp(object, factory()->false_value());
2463 __ j(not_equal, miss); 2486 __ j(not_equal, miss);
2464 __ bind(&success); 2487 __ bind(&success);
2465 } 2488 }
2466 2489
2467 2490
2468 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2491 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
2469 if (!object.is_null() && object->IsGlobalObject()) { 2492 if (object->IsGlobalObject()) {
2470 const int argc = arguments().immediate(); 2493 const int argc = arguments().immediate();
2471 const int receiver_offset = (argc + 1) * kPointerSize; 2494 const int receiver_offset = (argc + 1) * kPointerSize;
2472 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2495 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2473 __ mov(Operand(esp, receiver_offset), edx); 2496 __ mov(Operand(esp, receiver_offset), edx);
2474 } 2497 }
2475 } 2498 }
2476 2499
2477 2500
2478 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2501 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
2479 Handle<JSObject> holder, 2502 Handle<JSObject> holder,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2572 Handle<Object> prototype(object->GetPrototype(isolate()), isolate());
2550 reg = CheckPrototypes( 2573 reg = CheckPrototypes(
2551 IC::CurrentTypeOf(prototype, isolate()), 2574 IC::CurrentTypeOf(prototype, isolate()),
2552 eax, holder, ebx, edx, edi, name, miss); 2575 eax, holder, ebx, edx, edi, name, miss);
2553 } 2576 }
2554 2577
2555 return reg; 2578 return reg;
2556 } 2579 }
2557 2580
2558 2581
2559 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 2582 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2560 Register function, 2583 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2561 Label* miss) { 2584 ? CALL_AS_FUNCTION
2562 // Check that the function really is a function. 2585 : CALL_AS_METHOD;
2563 GenerateFunctionCheck(function, ebx, miss); 2586 ParameterCount expected(function);
2564 2587 __ InvokeFunction(function, expected, arguments(),
2565 if (!function.is(edi)) __ mov(edi, function); 2588 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2566 PatchGlobalProxy(object);
2567
2568 // Invoke the function.
2569 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2570 NullCallWrapper(), call_kind());
2571 } 2589 }
2572 2590
2573 2591
2592 Handle<Code> CallStubCompiler::CompileCallConstant(
2593 Handle<Object> object,
2594 Handle<JSObject> holder,
2595 Handle<Name> name,
2596 CheckType check,
2597 Handle<JSFunction> function) {
2598
2599 if (HasCustomCallGenerator(function)) {
2600 Handle<Code> code = CompileCustomCall(object, holder,
2601 Handle<Cell>::null(),
2602 function, Handle<String>::cast(name),
2603 Code::FAST);
2604 // A null handle means bail out to the regular compiler code below.
2605 if (!code.is_null()) return code;
2606 }
2607
2608 Label miss;
2609 HandlerFrontendHeader(object, holder, name, check, &miss);
2610 PatchGlobalProxy(object);
2611 CompileHandlerBackend(function);
2612 HandlerFrontendFooter(&miss);
2613
2614 // Return the generated code.
2615 return GetCode(function);
2616 }
2617
2618
2574 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2619 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2575 Handle<JSObject> holder, 2620 Handle<JSObject> holder,
2576 Handle<Name> name) { 2621 Handle<Name> name) {
2577 Label miss; 2622 Label miss;
2578 2623
2579 GenerateNameCheck(name, &miss); 2624 GenerateNameCheck(name, &miss);
2580 2625
2581 // Get the number of arguments. 2626 // Get the number of arguments.
2582 const int argc = arguments().immediate(); 2627 const int argc = arguments().immediate();
2583 2628
2584 LookupResult lookup(isolate()); 2629 LookupResult lookup(isolate());
2585 LookupPostInterceptor(holder, name, &lookup); 2630 LookupPostInterceptor(holder, name, &lookup);
2586 2631
2587 // Get the receiver from the stack. 2632 // Get the receiver from the stack.
2588 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2633 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2589 2634
2590 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); 2635 CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_);
2591 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, 2636 compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
2592 &miss); 2637 &miss);
2593 2638
2594 // Restore receiver. 2639 // Restore receiver.
2595 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2640 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2596 2641
2597 GenerateJumpFunction(object, eax, &miss); 2642 // Check that the function really is a function.
2643 __ JumpIfSmi(eax, &miss);
2644 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2645 __ j(not_equal, &miss);
2598 2646
2599 HandlerFrontendFooter(&miss); 2647 // Patch the receiver on the stack with the global proxy if
2648 // necessary.
2649 if (object->IsGlobalObject()) {
2650 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2651 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2652 }
2653
2654 // Invoke the function.
2655 __ mov(edi, eax);
2656 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2657 ? CALL_AS_FUNCTION
2658 : CALL_AS_METHOD;
2659 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2660 NullCallWrapper(), call_kind);
2661
2662 // Handle load cache miss.
2663 __ bind(&miss);
2664 GenerateMissBranch();
2600 2665
2601 // Return the generated code. 2666 // Return the generated code.
2602 return GetCode(Code::FAST, name); 2667 return GetCode(Code::FAST, name);
2603 } 2668 }
2604 2669
2605 2670
2606 Handle<Code> CallStubCompiler::CompileCallGlobal( 2671 Handle<Code> CallStubCompiler::CompileCallGlobal(
2607 Handle<JSObject> object, 2672 Handle<JSObject> object,
2608 Handle<GlobalObject> holder, 2673 Handle<GlobalObject> holder,
2609 Handle<PropertyCell> cell, 2674 Handle<PropertyCell> cell,
2610 Handle<JSFunction> function, 2675 Handle<JSFunction> function,
2611 Handle<Name> name) { 2676 Handle<Name> name) {
2612 if (HasCustomCallGenerator(function)) { 2677 if (HasCustomCallGenerator(function)) {
2613 Handle<Code> code = CompileCustomCall( 2678 Handle<Code> code = CompileCustomCall(
2614 object, holder, cell, function, Handle<String>::cast(name), 2679 object, holder, cell, function, Handle<String>::cast(name),
2615 Code::NORMAL); 2680 Code::NORMAL);
2616 // A null handle means bail out to the regular compiler code below. 2681 // A null handle means bail out to the regular compiler code below.
2617 if (!code.is_null()) return code; 2682 if (!code.is_null()) return code;
2618 } 2683 }
2619 2684
2620 Label miss; 2685 Label miss;
2621 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2686 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
2622 // Potentially loads a closure that matches the shared function info of the
2623 // function, rather than function.
2624 GenerateLoadFunctionFromCell(cell, function, &miss); 2687 GenerateLoadFunctionFromCell(cell, function, &miss);
2625 GenerateJumpFunction(object, edi, function); 2688 PatchGlobalProxy(object);
2689
2690 // Set up the context (function already in edi).
2691 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2692
2693 // Jump to the cached code (tail call).
2694 Counters* counters = isolate()->counters();
2695 __ IncrementCounter(counters->call_global_inline(), 1);
2696 ParameterCount expected(function->shared()->formal_parameter_count());
2697 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2698 ? CALL_AS_FUNCTION
2699 : CALL_AS_METHOD;
2700 // We call indirectly through the code field in the function to
2701 // allow recompilation to take effect without changing any of the
2702 // call sites.
2703 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2704 expected, arguments(), JUMP_FUNCTION,
2705 NullCallWrapper(), call_kind);
2626 2706
2627 HandlerFrontendFooter(&miss); 2707 HandlerFrontendFooter(&miss);
2628 2708
2629 // Return the generated code. 2709 // Return the generated code.
2630 return GetCode(Code::NORMAL, name); 2710 return GetCode(Code::NORMAL, name);
2631 } 2711 }
2632 2712
2633 2713
2634 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2714 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2635 Handle<JSObject> object, 2715 Handle<JSObject> object,
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2990 // ----------------------------------- 3070 // -----------------------------------
2991 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 3071 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
2992 } 3072 }
2993 3073
2994 3074
2995 #undef __ 3075 #undef __
2996 3076
2997 } } // namespace v8::internal 3077 } } // namespace v8::internal
2998 3078
2999 #endif // V8_TARGET_ARCH_IA32 3079 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698