OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3215 __ j(zero, label); | 3215 __ j(zero, label); |
3216 } | 3216 } |
3217 | 3217 |
3218 | 3218 |
3219 void StackCheckStub::Generate(MacroAssembler* masm) { | 3219 void StackCheckStub::Generate(MacroAssembler* masm) { |
3220 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); | 3220 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); |
3221 } | 3221 } |
3222 | 3222 |
3223 | 3223 |
3224 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3224 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3225 Label slow; | 3225 Label slow, non_function; |
3226 | 3226 |
3227 // The receiver might implicitly be the global object. This is | 3227 // The receiver might implicitly be the global object. This is |
3228 // indicated by passing the hole as the receiver to the call | 3228 // indicated by passing the hole as the receiver to the call |
3229 // function stub. | 3229 // function stub. |
3230 if (ReceiverMightBeImplicit()) { | 3230 if (ReceiverMightBeImplicit()) { |
3231 Label call; | 3231 Label call; |
3232 // Get the receiver from the stack. | 3232 // Get the receiver from the stack. |
3233 // +1 ~ return address | 3233 // +1 ~ return address |
3234 __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize)); | 3234 __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize)); |
3235 // Call as function is indicated with the hole. | 3235 // Call as function is indicated with the hole. |
3236 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 3236 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
3237 __ j(not_equal, &call, Label::kNear); | 3237 __ j(not_equal, &call, Label::kNear); |
3238 // Patch the receiver on the stack with the global receiver object. | 3238 // Patch the receiver on the stack with the global receiver object. |
3239 __ movq(rbx, GlobalObjectOperand()); | 3239 __ movq(rbx, GlobalObjectOperand()); |
3240 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 3240 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
3241 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx); | 3241 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rbx); |
3242 __ bind(&call); | 3242 __ bind(&call); |
3243 } | 3243 } |
3244 | 3244 |
3245 // Get the function to call from the stack. | 3245 // Get the function to call from the stack. |
3246 // +2 ~ receiver, return address | 3246 // +2 ~ receiver, return address |
3247 __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize)); | 3247 __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize)); |
3248 | 3248 |
3249 // Check that the function really is a JavaScript function. | 3249 // Check that the function really is a JavaScript function. |
3250 __ JumpIfSmi(rdi, &slow); | 3250 __ JumpIfSmi(rdi, &non_function); |
3251 // Goto slow case if we do not have a function. | 3251 // Goto slow case if we do not have a function. |
3252 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 3252 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
3253 __ j(not_equal, &slow); | 3253 __ j(not_equal, &slow); |
3254 | 3254 |
3255 // Fast-case: Just invoke the function. | 3255 // Fast-case: Just invoke the function. |
3256 ParameterCount actual(argc_); | 3256 ParameterCount actual(argc_); |
3257 | 3257 |
3258 if (ReceiverMightBeImplicit()) { | 3258 if (ReceiverMightBeImplicit()) { |
3259 Label call_as_function; | 3259 Label call_as_function; |
3260 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 3260 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
3261 __ j(equal, &call_as_function); | 3261 __ j(equal, &call_as_function); |
3262 __ InvokeFunction(rdi, | 3262 __ InvokeFunction(rdi, |
3263 actual, | 3263 actual, |
3264 JUMP_FUNCTION, | 3264 JUMP_FUNCTION, |
3265 NullCallWrapper(), | 3265 NullCallWrapper(), |
3266 CALL_AS_METHOD); | 3266 CALL_AS_METHOD); |
3267 __ bind(&call_as_function); | 3267 __ bind(&call_as_function); |
3268 } | 3268 } |
3269 __ InvokeFunction(rdi, | 3269 __ InvokeFunction(rdi, |
3270 actual, | 3270 actual, |
3271 JUMP_FUNCTION, | 3271 JUMP_FUNCTION, |
3272 NullCallWrapper(), | 3272 NullCallWrapper(), |
3273 CALL_AS_FUNCTION); | 3273 CALL_AS_FUNCTION); |
3274 | 3274 |
3275 // Slow-case: Non-function called. | 3275 // Slow-case: Non-function called. |
3276 __ bind(&slow); | 3276 __ bind(&slow); |
| 3277 // Check for function proxy. |
| 3278 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); |
| 3279 __ j(not_equal, &non_function); |
| 3280 __ pop(rcx); |
| 3281 __ push(rdi); // put proxy as additional argument under return address |
| 3282 __ push(rcx); |
| 3283 __ Set(rax, argc_ + 1); |
| 3284 __ Set(rbx, 0); |
| 3285 __ SetCallKind(rcx, CALL_AS_FUNCTION); |
| 3286 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); |
| 3287 { |
| 3288 Handle<Code> adaptor = |
| 3289 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 3290 __ jmp(adaptor, RelocInfo::CODE_TARGET); |
| 3291 } |
| 3292 |
3277 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3293 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
3278 // of the original receiver from the call site). | 3294 // of the original receiver from the call site). |
| 3295 __ bind(&non_function); |
3279 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); | 3296 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi); |
3280 __ Set(rax, argc_); | 3297 __ Set(rax, argc_); |
3281 __ Set(rbx, 0); | 3298 __ Set(rbx, 0); |
| 3299 __ SetCallKind(rcx, CALL_AS_METHOD); |
3282 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | 3300 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
3283 Handle<Code> adaptor = | 3301 Handle<Code> adaptor = |
3284 Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); | 3302 Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline(); |
3285 __ SetCallKind(rcx, CALL_AS_METHOD); | |
3286 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3303 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
3287 } | 3304 } |
3288 | 3305 |
3289 | 3306 |
3290 bool CEntryStub::NeedsImmovableCode() { | 3307 bool CEntryStub::NeedsImmovableCode() { |
3291 return false; | 3308 return false; |
3292 } | 3309 } |
3293 | 3310 |
3294 | 3311 |
3295 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 3312 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5366 __ Drop(1); | 5383 __ Drop(1); |
5367 __ ret(2 * kPointerSize); | 5384 __ ret(2 * kPointerSize); |
5368 } | 5385 } |
5369 | 5386 |
5370 | 5387 |
5371 #undef __ | 5388 #undef __ |
5372 | 5389 |
5373 } } // namespace v8::internal | 5390 } } // namespace v8::internal |
5374 | 5391 |
5375 #endif // V8_TARGET_ARCH_X64 | 5392 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |