| OLD | NEW | 
|     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 2555 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2566  |  2566  | 
|  2567  |  2567  | 
|  2568 void FullCodeGenerator::CallIC(Handle<Code> code, |  2568 void FullCodeGenerator::CallIC(Handle<Code> code, | 
|  2569                                TypeFeedbackId ast_id) { |  2569                                TypeFeedbackId ast_id) { | 
|  2570   ic_total_count_++; |  2570   ic_total_count_++; | 
|  2571   __ call(code, RelocInfo::CODE_TARGET, ast_id); |  2571   __ call(code, RelocInfo::CODE_TARGET, ast_id); | 
|  2572 } |  2572 } | 
|  2573  |  2573  | 
|  2574  |  2574  | 
|  2575 // Code common for calls using the IC. |  2575 // Code common for calls using the IC. | 
|  2576 void FullCodeGenerator::EmitCallWithIC(Call* expr) { |  2576 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { | 
|  2577   Expression* callee = expr->expression(); |  2577   Expression* callee = expr->expression(); | 
|  2578   ZoneList<Expression*>* args = expr->arguments(); |  | 
|  2579   int arg_count = args->length(); |  | 
|  2580  |  2578  | 
|  2581   CallFunctionFlags flags; |  2579   CallIC::CallType call_type = callee->IsVariableProxy() | 
|  2582   // Get the target function; |  2580       ? CallIC::FUNCTION | 
|  2583   if (callee->IsVariableProxy()) { |  2581       : CallIC::METHOD; | 
 |  2582   // Get the target function. | 
 |  2583   if (call_type == CallIC::FUNCTION) { | 
|  2584     { StackValueContext context(this); |  2584     { StackValueContext context(this); | 
|  2585       EmitVariableLoad(callee->AsVariableProxy()); |  2585       EmitVariableLoad(callee->AsVariableProxy()); | 
|  2586       PrepareForBailout(callee, NO_REGISTERS); |  2586       PrepareForBailout(callee, NO_REGISTERS); | 
|  2587     } |  2587     } | 
|  2588     // Push undefined as receiver. This is patched in the method prologue if it |  2588     // Push undefined as receiver. This is patched in the method prologue if it | 
|  2589     // is a sloppy mode method. |  2589     // is a sloppy mode method. | 
|  2590     __ Push(isolate()->factory()->undefined_value()); |  2590     __ Push(isolate()->factory()->undefined_value()); | 
|  2591     flags = NO_CALL_FUNCTION_FLAGS; |  | 
|  2592   } else { |  2591   } else { | 
|  2593     // Load the function from the receiver. |  2592     // Load the function from the receiver. | 
|  2594     ASSERT(callee->IsProperty()); |  2593     ASSERT(callee->IsProperty()); | 
|  2595     __ movp(rax, Operand(rsp, 0)); |  2594     __ movp(rax, Operand(rsp, 0)); | 
|  2596     EmitNamedPropertyLoad(callee->AsProperty()); |  2595     EmitNamedPropertyLoad(callee->AsProperty()); | 
|  2597     PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |  2596     PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 
|  2598     // Push the target function under the receiver. |  2597     // Push the target function under the receiver. | 
|  2599     __ Push(Operand(rsp, 0)); |  2598     __ Push(Operand(rsp, 0)); | 
|  2600     __ movp(Operand(rsp, kPointerSize), rax); |  2599     __ movp(Operand(rsp, kPointerSize), rax); | 
|  2601     flags = CALL_AS_METHOD; |  | 
|  2602   } |  2600   } | 
|  2603  |  2601  | 
|  2604   // Load the arguments. |  2602   EmitCall(expr, call_type); | 
|  2605   { PreservePositionScope scope(masm()->positions_recorder()); |  | 
|  2606     for (int i = 0; i < arg_count; i++) { |  | 
|  2607       VisitForStackValue(args->at(i)); |  | 
|  2608     } |  | 
|  2609   } |  | 
|  2610  |  | 
|  2611   // Record source position for debugger. |  | 
|  2612   SetSourcePosition(expr->position()); |  | 
|  2613   CallFunctionStub stub(arg_count, flags); |  | 
|  2614   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  | 
|  2615   __ CallStub(&stub); |  | 
|  2616  |  | 
|  2617   RecordJSReturnSite(expr); |  | 
|  2618  |  | 
|  2619   // Restore context register. |  | 
|  2620   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  | 
|  2621  |  | 
|  2622   context()->DropAndPlug(1, rax); |  | 
|  2623 } |  2603 } | 
|  2624  |  2604  | 
|  2625  |  2605  | 
|  2626 // Common code for calls using the IC. |  2606 // Common code for calls using the IC. | 
|  2627 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |  2607 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 
|  2628                                             Expression* key) { |  2608                                                 Expression* key) { | 
|  2629   // Load the key. |  2609   // Load the key. | 
|  2630   VisitForAccumulatorValue(key); |  2610   VisitForAccumulatorValue(key); | 
|  2631  |  2611  | 
|  2632   Expression* callee = expr->expression(); |  2612   Expression* callee = expr->expression(); | 
|  2633   ZoneList<Expression*>* args = expr->arguments(); |  | 
|  2634   int arg_count = args->length(); |  | 
|  2635  |  2613  | 
|  2636   // Load the function from the receiver. |  2614   // Load the function from the receiver. | 
|  2637   ASSERT(callee->IsProperty()); |  2615   ASSERT(callee->IsProperty()); | 
|  2638   __ movp(rdx, Operand(rsp, 0)); |  2616   __ movp(rdx, Operand(rsp, 0)); | 
|  2639   EmitKeyedPropertyLoad(callee->AsProperty()); |  2617   EmitKeyedPropertyLoad(callee->AsProperty()); | 
|  2640   PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |  2618   PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 
|  2641  |  2619  | 
|  2642   // Push the target function under the receiver. |  2620   // Push the target function under the receiver. | 
|  2643   __ Push(Operand(rsp, 0)); |  2621   __ Push(Operand(rsp, 0)); | 
|  2644   __ movp(Operand(rsp, kPointerSize), rax); |  2622   __ movp(Operand(rsp, kPointerSize), rax); | 
|  2645  |  2623  | 
|  2646   // Load the arguments. |  2624   EmitCall(expr, CallIC::METHOD); | 
|  2647   { PreservePositionScope scope(masm()->positions_recorder()); |  | 
|  2648     for (int i = 0; i < arg_count; i++) { |  | 
|  2649       VisitForStackValue(args->at(i)); |  | 
|  2650     } |  | 
|  2651   } |  | 
|  2652  |  | 
|  2653   // Record source position for debugger. |  | 
|  2654   SetSourcePosition(expr->position()); |  | 
|  2655   CallFunctionStub stub(arg_count, CALL_AS_METHOD); |  | 
|  2656   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  | 
|  2657   __ CallStub(&stub); |  | 
|  2658  |  | 
|  2659   RecordJSReturnSite(expr); |  | 
|  2660   // Restore context register. |  | 
|  2661   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  | 
|  2662  |  | 
|  2663   context()->DropAndPlug(1, rax); |  | 
|  2664 } |  2625 } | 
|  2665  |  2626  | 
|  2666  |  2627  | 
|  2667 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |  2628 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) { | 
|  2668   // Code common for calls using the call stub. |  2629   // Load the arguments. | 
|  2669   ZoneList<Expression*>* args = expr->arguments(); |  2630   ZoneList<Expression*>* args = expr->arguments(); | 
|  2670   int arg_count = args->length(); |  2631   int arg_count = args->length(); | 
|  2671   { PreservePositionScope scope(masm()->positions_recorder()); |  2632   { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2672     for (int i = 0; i < arg_count; i++) { |  2633     for (int i = 0; i < arg_count; i++) { | 
|  2673       VisitForStackValue(args->at(i)); |  2634       VisitForStackValue(args->at(i)); | 
|  2674     } |  2635     } | 
|  2675   } |  2636   } | 
|  2676   // Record source position for debugger. |  2637  | 
 |  2638   // Record source position of the IC call. | 
|  2677   SetSourcePosition(expr->position()); |  2639   SetSourcePosition(expr->position()); | 
 |  2640   Handle<Code> ic = CallIC::initialize_stub( | 
 |  2641       isolate(), arg_count, call_type); | 
 |  2642   __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot())); | 
 |  2643   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 
 |  2644   // Don't assign a type feedback id to the IC, since type feedback is provided | 
 |  2645   // by the vector above. | 
 |  2646   CallIC(ic); | 
|  2678  |  2647  | 
|  2679   __ Move(rbx, FeedbackVector()); |  2648   RecordJSReturnSite(expr); | 
|  2680   __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot())); |  | 
|  2681  |  2649  | 
|  2682   // Record call targets in unoptimized code. |  | 
|  2683   CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); |  | 
|  2684   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  | 
|  2685   __ CallStub(&stub); |  | 
|  2686   RecordJSReturnSite(expr); |  | 
|  2687   // Restore context register. |  2650   // Restore context register. | 
|  2688   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2651   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2689   // Discard the function left on TOS. |  2652   // Discard the function left on TOS. | 
|  2690   context()->DropAndPlug(1, rax); |  2653   context()->DropAndPlug(1, rax); | 
|  2691 } |  2654 } | 
|  2692  |  2655  | 
|  2693  |  2656  | 
|  2694 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |  2657 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 
|  2695   // Push copy of the first argument or undefined if it doesn't exist. |  2658   // Push copy of the first argument or undefined if it doesn't exist. | 
|  2696   if (arg_count > 0) { |  2659   if (arg_count > 0) { | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2753     // Record source position for debugger. |  2716     // Record source position for debugger. | 
|  2754     SetSourcePosition(expr->position()); |  2717     SetSourcePosition(expr->position()); | 
|  2755     CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |  2718     CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 
|  2756     __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  2719     __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 
|  2757     __ CallStub(&stub); |  2720     __ CallStub(&stub); | 
|  2758     RecordJSReturnSite(expr); |  2721     RecordJSReturnSite(expr); | 
|  2759     // Restore context register. |  2722     // Restore context register. | 
|  2760     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2723     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2761     context()->DropAndPlug(1, rax); |  2724     context()->DropAndPlug(1, rax); | 
|  2762   } else if (call_type == Call::GLOBAL_CALL) { |  2725   } else if (call_type == Call::GLOBAL_CALL) { | 
|  2763     EmitCallWithIC(expr); |  2726     EmitCallWithLoadIC(expr); | 
|  2764  |  2727  | 
|  2765   } else if (call_type == Call::LOOKUP_SLOT_CALL) { |  2728   } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 
|  2766     // Call to a lookup slot (dynamically introduced variable). |  2729     // Call to a lookup slot (dynamically introduced variable). | 
|  2767     VariableProxy* proxy = callee->AsVariableProxy(); |  2730     VariableProxy* proxy = callee->AsVariableProxy(); | 
|  2768     Label slow, done; |  2731     Label slow, done; | 
|  2769  |  2732  | 
|  2770     { PreservePositionScope scope(masm()->positions_recorder()); |  2733     { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2771       // Generate code for loading from variables potentially shadowed by |  2734       // Generate code for loading from variables potentially shadowed by | 
|  2772       // eval-introduced variables. |  2735       // eval-introduced variables. | 
|  2773       EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |  2736       EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  2790       // Push function. |  2753       // Push function. | 
|  2791       __ Push(rax); |  2754       __ Push(rax); | 
|  2792       // The receiver is implicitly the global receiver. Indicate this by |  2755       // The receiver is implicitly the global receiver. Indicate this by | 
|  2793       // passing the hole to the call function stub. |  2756       // passing the hole to the call function stub. | 
|  2794       __ PushRoot(Heap::kUndefinedValueRootIndex); |  2757       __ PushRoot(Heap::kUndefinedValueRootIndex); | 
|  2795       __ bind(&call); |  2758       __ bind(&call); | 
|  2796     } |  2759     } | 
|  2797  |  2760  | 
|  2798     // The receiver is either the global receiver or an object found by |  2761     // The receiver is either the global receiver or an object found by | 
|  2799     // LoadContextSlot. |  2762     // LoadContextSlot. | 
|  2800     EmitCallWithStub(expr); |  2763     EmitCall(expr); | 
|  2801   } else if (call_type == Call::PROPERTY_CALL) { |  2764   } else if (call_type == Call::PROPERTY_CALL) { | 
|  2802     Property* property = callee->AsProperty(); |  2765     Property* property = callee->AsProperty(); | 
|  2803     { PreservePositionScope scope(masm()->positions_recorder()); |  2766     { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2804       VisitForStackValue(property->obj()); |  2767       VisitForStackValue(property->obj()); | 
|  2805     } |  2768     } | 
|  2806     if (property->key()->IsPropertyName()) { |  2769     if (property->key()->IsPropertyName()) { | 
|  2807       EmitCallWithIC(expr); |  2770       EmitCallWithLoadIC(expr); | 
|  2808     } else { |  2771     } else { | 
|  2809       EmitKeyedCallWithIC(expr, property->key()); |  2772       EmitKeyedCallWithLoadIC(expr, property->key()); | 
|  2810     } |  2773     } | 
|  2811   } else { |  2774   } else { | 
|  2812     ASSERT(call_type == Call::OTHER_CALL); |  2775     ASSERT(call_type == Call::OTHER_CALL); | 
|  2813     // Call to an arbitrary expression not handled specially above. |  2776     // Call to an arbitrary expression not handled specially above. | 
|  2814     { PreservePositionScope scope(masm()->positions_recorder()); |  2777     { PreservePositionScope scope(masm()->positions_recorder()); | 
|  2815       VisitForStackValue(callee); |  2778       VisitForStackValue(callee); | 
|  2816     } |  2779     } | 
|  2817     __ PushRoot(Heap::kUndefinedValueRootIndex); |  2780     __ PushRoot(Heap::kUndefinedValueRootIndex); | 
|  2818     // Emit function call. |  2781     // Emit function call. | 
|  2819     EmitCallWithStub(expr); |  2782     EmitCall(expr); | 
|  2820   } |  2783   } | 
|  2821  |  2784  | 
|  2822 #ifdef DEBUG |  2785 #ifdef DEBUG | 
|  2823   // RecordJSReturnSite should have been called. |  2786   // RecordJSReturnSite should have been called. | 
|  2824   ASSERT(expr->return_is_recorded_); |  2787   ASSERT(expr->return_is_recorded_); | 
|  2825 #endif |  2788 #endif | 
|  2826 } |  2789 } | 
|  2827  |  2790  | 
|  2828  |  2791  | 
|  2829 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |  2792 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  2855   // Record call targets in unoptimized code, but not in the snapshot. |  2818   // Record call targets in unoptimized code, but not in the snapshot. | 
|  2856   if (FLAG_pretenuring_call_new) { |  2819   if (FLAG_pretenuring_call_new) { | 
|  2857     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |  2820     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 
|  2858     ASSERT(expr->AllocationSiteFeedbackSlot() == |  2821     ASSERT(expr->AllocationSiteFeedbackSlot() == | 
|  2859            expr->CallNewFeedbackSlot() + 1); |  2822            expr->CallNewFeedbackSlot() + 1); | 
|  2860   } |  2823   } | 
|  2861  |  2824  | 
|  2862   __ Move(rbx, FeedbackVector()); |  2825   __ Move(rbx, FeedbackVector()); | 
|  2863   __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot())); |  2826   __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot())); | 
|  2864  |  2827  | 
|  2865   CallConstructStub stub(RECORD_CALL_TARGET); |  2828   CallConstructStub stub(RECORD_CONSTRUCTOR_TARGET); | 
|  2866   __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |  2829   __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 
|  2867   PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |  2830   PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 
|  2868   context()->Plug(rax); |  2831   context()->Plug(rax); | 
|  2869 } |  2832 } | 
|  2870  |  2833  | 
|  2871  |  2834  | 
|  2872 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |  2835 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 
|  2873   ZoneList<Expression*>* args = expr->arguments(); |  2836   ZoneList<Expression*>* args = expr->arguments(); | 
|  2874   ASSERT(args->length() == 1); |  2837   ASSERT(args->length() == 1); | 
|  2875  |  2838  | 
| (...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4910   ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |  4873   ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 
|  4911             Assembler::target_address_at(call_target_address, |  4874             Assembler::target_address_at(call_target_address, | 
|  4912                                          unoptimized_code)); |  4875                                          unoptimized_code)); | 
|  4913   return OSR_AFTER_STACK_CHECK; |  4876   return OSR_AFTER_STACK_CHECK; | 
|  4914 } |  4877 } | 
|  4915  |  4878  | 
|  4916  |  4879  | 
|  4917 } }  // namespace v8::internal |  4880 } }  // namespace v8::internal | 
|  4918  |  4881  | 
|  4919 #endif  // V8_TARGET_ARCH_X64 |  4882 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |