| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 | 
| 6 | 6 | 
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" | 
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" | 
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" | 
| 10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" | 
| (...skipping 2903 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2914       __ bind(&call); | 2914       __ bind(&call); | 
| 2915     } | 2915     } | 
| 2916   } else { | 2916   } else { | 
| 2917     VisitForStackValue(callee); | 2917     VisitForStackValue(callee); | 
| 2918     // refEnv.WithBaseObject() | 2918     // refEnv.WithBaseObject() | 
| 2919     __ PushRoot(Heap::kUndefinedValueRootIndex); | 2919     __ PushRoot(Heap::kUndefinedValueRootIndex); | 
| 2920   } | 2920   } | 
| 2921 } | 2921 } | 
| 2922 | 2922 | 
| 2923 | 2923 | 
| 2924 void FullCodeGenerator::VisitCall(Call* expr) { | 2924 void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { | 
| 2925 #ifdef DEBUG | 2925   // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 
| 2926   // We want to verify that RecordJSReturnSite gets called on all paths | 2926   // to resolve the function we need to call.  Then we call the resolved | 
| 2927   // through this function.  Avoid early returns. | 2927   // function using the given arguments. | 
| 2928   expr->return_is_recorded_ = false; | 2928   ZoneList<Expression*>* args = expr->arguments(); | 
| 2929 #endif | 2929   int arg_count = args->length(); | 
|  | 2930   PushCalleeAndWithBaseObject(expr); | 
| 2930 | 2931 | 
| 2931   Comment cmnt(masm_, "[ Call"); | 2932   // Push the arguments. | 
| 2932   Expression* callee = expr->expression(); | 2933   for (int i = 0; i < arg_count; i++) { | 
| 2933   Call::CallType call_type = expr->GetCallType(isolate()); | 2934     VisitForStackValue(args->at(i)); | 
| 2934 |  | 
| 2935   if (call_type == Call::POSSIBLY_EVAL_CALL) { |  | 
| 2936     // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |  | 
| 2937     // to resolve the function we need to call.  Then we call the resolved |  | 
| 2938     // function using the given arguments. |  | 
| 2939     ZoneList<Expression*>* args = expr->arguments(); |  | 
| 2940     int arg_count = args->length(); |  | 
| 2941     PushCalleeAndWithBaseObject(expr); |  | 
| 2942 |  | 
| 2943     // Push the arguments. |  | 
| 2944     for (int i = 0; i < arg_count; i++) { |  | 
| 2945       VisitForStackValue(args->at(i)); |  | 
| 2946     } |  | 
| 2947 |  | 
| 2948     // Push a copy of the function (found below the arguments) and resolve |  | 
| 2949     // eval. |  | 
| 2950     __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); |  | 
| 2951     EmitResolvePossiblyDirectEval(arg_count); |  | 
| 2952 |  | 
| 2953     // Touch up the callee. |  | 
| 2954     __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); |  | 
| 2955 |  | 
| 2956     PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |  | 
| 2957 |  | 
| 2958     SetCallPosition(expr, arg_count); |  | 
| 2959     CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |  | 
| 2960     __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |  | 
| 2961     __ CallStub(&stub); |  | 
| 2962     RecordJSReturnSite(expr); |  | 
| 2963     // Restore context register. |  | 
| 2964     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  | 
| 2965     context()->DropAndPlug(1, rax); |  | 
| 2966   } else if (call_type == Call::GLOBAL_CALL) { |  | 
| 2967     EmitCallWithLoadIC(expr); |  | 
| 2968 |  | 
| 2969   } else if (call_type == Call::LOOKUP_SLOT_CALL) { |  | 
| 2970     // Call to a lookup slot (dynamically introduced variable). |  | 
| 2971     PushCalleeAndWithBaseObject(expr); |  | 
| 2972     EmitCall(expr); |  | 
| 2973   } else if (call_type == Call::NAMED_PROPERTY_CALL) { |  | 
| 2974     Property* property = callee->AsProperty(); |  | 
| 2975     VisitForStackValue(property->obj()); |  | 
| 2976     EmitCallWithLoadIC(expr); |  | 
| 2977   } else if (call_type == Call::KEYED_PROPERTY_CALL) { |  | 
| 2978     Property* property = callee->AsProperty(); |  | 
| 2979     VisitForStackValue(property->obj()); |  | 
| 2980     EmitKeyedCallWithLoadIC(expr, property->key()); |  | 
| 2981   } else if (call_type == Call::NAMED_SUPER_PROPERTY_CALL) { |  | 
| 2982     EmitSuperCallWithLoadIC(expr); |  | 
| 2983   } else if (call_type == Call::KEYED_SUPER_PROPERTY_CALL) { |  | 
| 2984     EmitKeyedSuperCallWithLoadIC(expr); |  | 
| 2985   } else if (call_type == Call::SUPER_CALL) { |  | 
| 2986     EmitSuperConstructorCall(expr); |  | 
| 2987   } else { |  | 
| 2988     DCHECK(call_type == Call::OTHER_CALL); |  | 
| 2989     // Call to an arbitrary expression not handled specially above. |  | 
| 2990       VisitForStackValue(callee); |  | 
| 2991     __ PushRoot(Heap::kUndefinedValueRootIndex); |  | 
| 2992     // Emit function call. |  | 
| 2993     EmitCall(expr); |  | 
| 2994   } | 2935   } | 
| 2995 | 2936 | 
| 2996 #ifdef DEBUG | 2937   // Push a copy of the function (found below the arguments) and resolve | 
| 2997   // RecordJSReturnSite should have been called. | 2938   // eval. | 
| 2998   DCHECK(expr->return_is_recorded_); | 2939   __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); | 
| 2999 #endif | 2940   EmitResolvePossiblyDirectEval(arg_count); | 
|  | 2941 | 
|  | 2942   // Touch up the callee. | 
|  | 2943   __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); | 
|  | 2944 | 
|  | 2945   PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 
|  | 2946 | 
|  | 2947   SetCallPosition(expr, arg_count); | 
|  | 2948   CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 
|  | 2949   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 
|  | 2950   __ CallStub(&stub); | 
|  | 2951   RecordJSReturnSite(expr); | 
|  | 2952   // Restore context register. | 
|  | 2953   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  | 2954   context()->DropAndPlug(1, rax); | 
| 3000 } | 2955 } | 
| 3001 | 2956 | 
| 3002 | 2957 | 
| 3003 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2958 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 
| 3004   Comment cmnt(masm_, "[ CallNew"); | 2959   Comment cmnt(masm_, "[ CallNew"); | 
| 3005   // According to ECMA-262, section 11.2.2, page 44, the function | 2960   // According to ECMA-262, section 11.2.2, page 44, the function | 
| 3006   // expression in new calls must be evaluated before the | 2961   // expression in new calls must be evaluated before the | 
| 3007   // arguments. | 2962   // arguments. | 
| 3008 | 2963 | 
| 3009   // Push constructor on the stack.  If it's not a function it's used as | 2964   // Push constructor on the stack.  If it's not a function it's used as | 
| (...skipping 2065 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5075             Assembler::target_address_at(call_target_address, | 5030             Assembler::target_address_at(call_target_address, | 
| 5076                                          unoptimized_code)); | 5031                                          unoptimized_code)); | 
| 5077   return OSR_AFTER_STACK_CHECK; | 5032   return OSR_AFTER_STACK_CHECK; | 
| 5078 } | 5033 } | 
| 5079 | 5034 | 
| 5080 | 5035 | 
| 5081 }  // namespace internal | 5036 }  // namespace internal | 
| 5082 }  // namespace v8 | 5037 }  // namespace v8 | 
| 5083 | 5038 | 
| 5084 #endif  // V8_TARGET_ARCH_X64 | 5039 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|