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/ia32/stub-cache-ia32.cc

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