| 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 |