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 2201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 } | 2212 } |
2213 __ Move(rcx, name); | 2213 __ Move(rcx, name); |
2214 } | 2214 } |
2215 // Record source position for debugger. | 2215 // Record source position for debugger. |
2216 SetSourcePosition(expr->position()); | 2216 SetSourcePosition(expr->position()); |
2217 // Call the IC initialization code. | 2217 // Call the IC initialization code. |
2218 Handle<Code> ic = | 2218 Handle<Code> ic = |
2219 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2219 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2220 CallIC(ic, mode, expr->CallFeedbackId()); | 2220 CallIC(ic, mode, expr->CallFeedbackId()); |
2221 RecordJSReturnSite(expr); | 2221 RecordJSReturnSite(expr); |
2222 // Restore context register. | 2222 __ ReloadContextFromFrame(); |
2223 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2224 context()->Plug(rax); | 2223 context()->Plug(rax); |
2225 } | 2224 } |
2226 | 2225 |
2227 | 2226 |
2228 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2227 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2229 Expression* key) { | 2228 Expression* key) { |
2230 // Load the key. | 2229 // Load the key. |
2231 VisitForAccumulatorValue(key); | 2230 VisitForAccumulatorValue(key); |
2232 | 2231 |
2233 // Swap the name of the function and the receiver on the stack to follow | 2232 // Swap the name of the function and the receiver on the stack to follow |
(...skipping 11 matching lines...) Expand all Loading... |
2245 } | 2244 } |
2246 } | 2245 } |
2247 // Record source position for debugger. | 2246 // Record source position for debugger. |
2248 SetSourcePosition(expr->position()); | 2247 SetSourcePosition(expr->position()); |
2249 // Call the IC initialization code. | 2248 // Call the IC initialization code. |
2250 Handle<Code> ic = | 2249 Handle<Code> ic = |
2251 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2250 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2252 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2251 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
2253 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2252 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); |
2254 RecordJSReturnSite(expr); | 2253 RecordJSReturnSite(expr); |
2255 // Restore context register. | 2254 __ ReloadContextFromFrame(); |
2256 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2257 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2255 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
2258 } | 2256 } |
2259 | 2257 |
2260 | 2258 |
2261 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2259 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2262 // Code common for calls using the call stub. | 2260 // Code common for calls using the call stub. |
2263 ZoneList<Expression*>* args = expr->arguments(); | 2261 ZoneList<Expression*>* args = expr->arguments(); |
2264 int arg_count = args->length(); | 2262 int arg_count = args->length(); |
2265 { PreservePositionScope scope(masm()->positions_recorder()); | 2263 { PreservePositionScope scope(masm()->positions_recorder()); |
2266 for (int i = 0; i < arg_count; i++) { | 2264 for (int i = 0; i < arg_count; i++) { |
2267 VisitForStackValue(args->at(i)); | 2265 VisitForStackValue(args->at(i)); |
2268 } | 2266 } |
2269 } | 2267 } |
2270 // Record source position for debugger. | 2268 // Record source position for debugger. |
2271 SetSourcePosition(expr->position()); | 2269 SetSourcePosition(expr->position()); |
2272 | 2270 |
2273 // Record call targets in unoptimized code. | 2271 // Record call targets in unoptimized code. |
2274 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2272 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
2275 Handle<Object> uninitialized = | 2273 Handle<Object> uninitialized = |
2276 TypeFeedbackCells::UninitializedSentinel(isolate()); | 2274 TypeFeedbackCells::UninitializedSentinel(isolate()); |
2277 Handle<JSGlobalPropertyCell> cell = | 2275 Handle<JSGlobalPropertyCell> cell = |
2278 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2276 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
2279 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); | 2277 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); |
2280 __ Move(rbx, cell); | 2278 __ Move(rbx, cell); |
2281 | 2279 |
2282 CallFunctionStub stub(arg_count, flags); | 2280 CallFunctionStub stub(arg_count, flags); |
2283 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2281 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2284 __ CallStub(&stub, expr->CallFeedbackId()); | 2282 __ CallStub(&stub, expr->CallFeedbackId()); |
2285 RecordJSReturnSite(expr); | 2283 RecordJSReturnSite(expr); |
2286 // Restore context register. | 2284 __ ReloadContextFromFrame(); |
2287 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2288 // Discard the function left on TOS. | 2285 // Discard the function left on TOS. |
2289 context()->DropAndPlug(1, rax); | 2286 context()->DropAndPlug(1, rax); |
2290 } | 2287 } |
2291 | 2288 |
2292 | 2289 |
2293 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2290 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2294 // Push copy of the first argument or undefined if it doesn't exist. | 2291 // Push copy of the first argument or undefined if it doesn't exist. |
2295 if (arg_count > 0) { | 2292 if (arg_count > 0) { |
2296 __ push(Operand(rsp, arg_count * kPointerSize)); | 2293 __ push(Operand(rsp, arg_count * kPointerSize)); |
2297 } else { | 2294 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 // rdx (receiver). Touch up the stack with the right values. | 2345 // rdx (receiver). Touch up the stack with the right values. |
2349 __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); | 2346 __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); |
2350 __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax); | 2347 __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax); |
2351 } | 2348 } |
2352 // Record source position for debugger. | 2349 // Record source position for debugger. |
2353 SetSourcePosition(expr->position()); | 2350 SetSourcePosition(expr->position()); |
2354 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); | 2351 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); |
2355 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2352 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2356 __ CallStub(&stub); | 2353 __ CallStub(&stub); |
2357 RecordJSReturnSite(expr); | 2354 RecordJSReturnSite(expr); |
2358 // Restore context register. | 2355 __ ReloadContextFromFrame(); |
2359 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
2360 context()->DropAndPlug(1, rax); | 2356 context()->DropAndPlug(1, rax); |
2361 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2357 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
2362 // Call to a global variable. Push global object as receiver for the | 2358 // Call to a global variable. Push global object as receiver for the |
2363 // call IC lookup. | 2359 // call IC lookup. |
2364 __ push(GlobalObjectOperand()); | 2360 __ push(GlobalObjectOperand()); |
2365 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2361 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); |
2366 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2362 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
2367 // Call to a lookup slot (dynamically introduced variable). | 2363 // Call to a lookup slot (dynamically introduced variable). |
2368 Label slow, done; | 2364 Label slow, done; |
2369 | 2365 |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3047 __ bind(&runtime); | 3043 __ bind(&runtime); |
3048 __ PrepareCallCFunction(2); | 3044 __ PrepareCallCFunction(2); |
3049 #ifdef _WIN64 | 3045 #ifdef _WIN64 |
3050 __ movq(rcx, object); | 3046 __ movq(rcx, object); |
3051 __ movq(rdx, index, RelocInfo::NONE64); | 3047 __ movq(rdx, index, RelocInfo::NONE64); |
3052 #else | 3048 #else |
3053 __ movq(rdi, object); | 3049 __ movq(rdi, object); |
3054 __ movq(rsi, index, RelocInfo::NONE64); | 3050 __ movq(rsi, index, RelocInfo::NONE64); |
3055 #endif | 3051 #endif |
3056 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3052 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
3057 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3053 __ ReloadContextFromFrame(); |
3058 __ jmp(&done); | 3054 __ jmp(&done); |
3059 } | 3055 } |
3060 | 3056 |
3061 __ bind(¬_date_object); | 3057 __ bind(¬_date_object); |
3062 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3058 __ CallRuntime(Runtime::kThrowNotDateError, 0); |
3063 __ bind(&done); | 3059 __ bind(&done); |
3064 context()->Plug(rax); | 3060 context()->Plug(rax); |
3065 } | 3061 } |
3066 | 3062 |
3067 | 3063 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3361 // Check for non-function argument (including proxy). | 3357 // Check for non-function argument (including proxy). |
3362 __ JumpIfSmi(rax, &runtime); | 3358 __ JumpIfSmi(rax, &runtime); |
3363 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 3359 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
3364 __ j(not_equal, &runtime); | 3360 __ j(not_equal, &runtime); |
3365 | 3361 |
3366 // InvokeFunction requires the function in rdi. Move it in there. | 3362 // InvokeFunction requires the function in rdi. Move it in there. |
3367 __ movq(rdi, result_register()); | 3363 __ movq(rdi, result_register()); |
3368 ParameterCount count(arg_count); | 3364 ParameterCount count(arg_count); |
3369 __ InvokeFunction(rdi, count, CALL_FUNCTION, | 3365 __ InvokeFunction(rdi, count, CALL_FUNCTION, |
3370 NullCallWrapper(), CALL_AS_METHOD); | 3366 NullCallWrapper(), CALL_AS_METHOD); |
3371 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3367 __ ReloadContextFromFrame(); |
3372 __ jmp(&done); | 3368 __ jmp(&done); |
3373 | 3369 |
3374 __ bind(&runtime); | 3370 __ bind(&runtime); |
3375 __ push(rax); | 3371 __ push(rax); |
3376 __ CallRuntime(Runtime::kCall, args->length()); | 3372 __ CallRuntime(Runtime::kCall, args->length()); |
3377 __ bind(&done); | 3373 __ bind(&done); |
3378 | 3374 |
3379 context()->Plug(rax); | 3375 context()->Plug(rax); |
3380 } | 3376 } |
3381 | 3377 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3799 __ CopyBytes(result_pos, string, string_length); | 3795 __ CopyBytes(result_pos, string, string_length); |
3800 __ incq(index); | 3796 __ incq(index); |
3801 __ j(not_equal, &loop_3); // Loop while (index < 0). | 3797 __ j(not_equal, &loop_3); // Loop while (index < 0). |
3802 | 3798 |
3803 __ bind(&done); | 3799 __ bind(&done); |
3804 __ movq(rax, result_operand); | 3800 __ movq(rax, result_operand); |
3805 | 3801 |
3806 __ bind(&return_result); | 3802 __ bind(&return_result); |
3807 // Drop temp values from the stack, and restore context register. | 3803 // Drop temp values from the stack, and restore context register. |
3808 __ addq(rsp, Immediate(3 * kPointerSize)); | 3804 __ addq(rsp, Immediate(3 * kPointerSize)); |
3809 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3805 __ ReloadContextFromFrame(); |
3810 context()->Plug(rax); | 3806 context()->Plug(rax); |
3811 } | 3807 } |
3812 | 3808 |
3813 | 3809 |
3814 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 3810 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
3815 Handle<String> name = expr->name(); | 3811 Handle<String> name = expr->name(); |
3816 if (name->length() > 0 && name->Get(0) == '_') { | 3812 if (name->length() > 0 && name->Get(0) == '_') { |
3817 Comment cmnt(masm_, "[ InlineRuntimeCall"); | 3813 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
3818 EmitInlineRuntimeCall(expr); | 3814 EmitInlineRuntimeCall(expr); |
3819 return; | 3815 return; |
(...skipping 14 matching lines...) Expand all Loading... |
3834 VisitForStackValue(args->at(i)); | 3830 VisitForStackValue(args->at(i)); |
3835 } | 3831 } |
3836 | 3832 |
3837 if (expr->is_jsruntime()) { | 3833 if (expr->is_jsruntime()) { |
3838 // Call the JS runtime function using a call IC. | 3834 // Call the JS runtime function using a call IC. |
3839 __ Move(rcx, expr->name()); | 3835 __ Move(rcx, expr->name()); |
3840 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3836 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
3841 Handle<Code> ic = | 3837 Handle<Code> ic = |
3842 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 3838 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
3843 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 3839 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
3844 // Restore context register. | 3840 __ ReloadContextFromFrame(); |
3845 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
3846 } else { | 3841 } else { |
3847 __ CallRuntime(expr->function(), arg_count); | 3842 __ CallRuntime(expr->function(), arg_count); |
3848 } | 3843 } |
3849 context()->Plug(rax); | 3844 context()->Plug(rax); |
3850 } | 3845 } |
3851 | 3846 |
3852 | 3847 |
3853 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3848 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3854 switch (expr->op()) { | 3849 switch (expr->op()) { |
3855 case Token::DELETE: { | 3850 case Token::DELETE: { |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4551 *context_length = 0; | 4546 *context_length = 0; |
4552 return previous_; | 4547 return previous_; |
4553 } | 4548 } |
4554 | 4549 |
4555 | 4550 |
4556 #undef __ | 4551 #undef __ |
4557 | 4552 |
4558 } } // namespace v8::internal | 4553 } } // namespace v8::internal |
4559 | 4554 |
4560 #endif // V8_TARGET_ARCH_X64 | 4555 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |