OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2798 } | 2798 } |
2799 | 2799 |
2800 | 2800 |
2801 void FullCodeGenerator::EmitLoadSuperConstructor() { | 2801 void FullCodeGenerator::EmitLoadSuperConstructor() { |
2802 __ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 2802 __ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
2803 __ Push(x0); | 2803 __ Push(x0); |
2804 __ CallRuntime(Runtime::kGetPrototype, 1); | 2804 __ CallRuntime(Runtime::kGetPrototype, 1); |
2805 } | 2805 } |
2806 | 2806 |
2807 | 2807 |
| 2808 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2809 SuperReference* super_ref) { |
| 2810 Variable* this_var = super_ref->this_var()->var(); |
| 2811 GetVar(x1, this_var); |
| 2812 Label uninitialized_this; |
| 2813 __ JumpIfRoot(x1, Heap::kTheHoleValueRootIndex, &uninitialized_this); |
| 2814 __ Mov(x0, Operand(this_var->name())); |
| 2815 __ Push(x0); |
| 2816 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2817 __ bind(&uninitialized_this); |
| 2818 |
| 2819 EmitVariableAssignment(this_var, Token::INIT_CONST); |
| 2820 } |
| 2821 |
| 2822 |
2808 void FullCodeGenerator::VisitCall(Call* expr) { | 2823 void FullCodeGenerator::VisitCall(Call* expr) { |
2809 #ifdef DEBUG | 2824 #ifdef DEBUG |
2810 // We want to verify that RecordJSReturnSite gets called on all paths | 2825 // We want to verify that RecordJSReturnSite gets called on all paths |
2811 // through this function. Avoid early returns. | 2826 // through this function. Avoid early returns. |
2812 expr->return_is_recorded_ = false; | 2827 expr->return_is_recorded_ = false; |
2813 #endif | 2828 #endif |
2814 | 2829 |
2815 Comment cmnt(masm_, "[ Call"); | 2830 Comment cmnt(masm_, "[ Call"); |
2816 Expression* callee = expr->expression(); | 2831 Expression* callee = expr->expression(); |
2817 Call::CallType call_type = expr->GetCallType(isolate()); | 2832 Call::CallType call_type = expr->GetCallType(isolate()); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3022 __ LoadObject(x2, FeedbackVector()); | 3037 __ LoadObject(x2, FeedbackVector()); |
3023 __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot())); | 3038 __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot())); |
3024 | 3039 |
3025 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3040 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3026 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3041 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3027 | 3042 |
3028 __ Drop(1); | 3043 __ Drop(1); |
3029 | 3044 |
3030 RecordJSReturnSite(expr); | 3045 RecordJSReturnSite(expr); |
3031 | 3046 |
3032 SuperReference* super_ref = expr->expression()->AsSuperReference(); | 3047 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); |
3033 Variable* this_var = super_ref->this_var()->var(); | |
3034 GetVar(x1, this_var); | |
3035 Label uninitialized_this; | |
3036 __ JumpIfRoot(x1, Heap::kTheHoleValueRootIndex, &uninitialized_this); | |
3037 __ Mov(x0, Operand(this_var->name())); | |
3038 __ Push(x0); | |
3039 __ CallRuntime(Runtime::kThrowReferenceError, 1); | |
3040 __ bind(&uninitialized_this); | |
3041 | |
3042 EmitVariableAssignment(this_var, Token::INIT_CONST); | |
3043 context()->Plug(x0); | 3048 context()->Plug(x0); |
3044 } | 3049 } |
3045 | 3050 |
3046 | 3051 |
3047 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3052 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3048 ZoneList<Expression*>* args = expr->arguments(); | 3053 ZoneList<Expression*>* args = expr->arguments(); |
3049 DCHECK(args->length() == 1); | 3054 DCHECK(args->length() == 1); |
3050 | 3055 |
3051 VisitForAccumulatorValue(args->at(0)); | 3056 VisitForAccumulatorValue(args->at(0)); |
3052 | 3057 |
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4287 DCHECK(expr->arguments()->length() == 0); | 4292 DCHECK(expr->arguments()->length() == 0); |
4288 ExternalReference debug_is_active = | 4293 ExternalReference debug_is_active = |
4289 ExternalReference::debug_is_active_address(isolate()); | 4294 ExternalReference::debug_is_active_address(isolate()); |
4290 __ Mov(x10, debug_is_active); | 4295 __ Mov(x10, debug_is_active); |
4291 __ Ldrb(x0, MemOperand(x10)); | 4296 __ Ldrb(x0, MemOperand(x10)); |
4292 __ SmiTag(x0); | 4297 __ SmiTag(x0); |
4293 context()->Plug(x0); | 4298 context()->Plug(x0); |
4294 } | 4299 } |
4295 | 4300 |
4296 | 4301 |
| 4302 void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) { |
| 4303 // Assert: expr === CallRuntime("ReflectConstruct") |
| 4304 CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime(); |
| 4305 ZoneList<Expression*>* args = call->arguments(); |
| 4306 DCHECK_EQ(3, args->length()); |
| 4307 |
| 4308 SuperReference* super_reference = args->at(0)->AsSuperReference(); |
| 4309 |
| 4310 // Load ReflectConstruct function |
| 4311 EmitLoadJSRuntimeFunction(call); |
| 4312 |
| 4313 // Push the target function under the receiver. |
| 4314 __ Pop(x10); |
| 4315 __ Push(x0, x10); |
| 4316 |
| 4317 // Push super |
| 4318 EmitLoadSuperConstructor(); |
| 4319 __ Push(result_register()); |
| 4320 |
| 4321 // Push arguments array |
| 4322 VisitForStackValue(args->at(1)); |
| 4323 |
| 4324 // Push NewTarget |
| 4325 DCHECK(args->at(2)->IsVariableProxy()); |
| 4326 VisitForStackValue(args->at(2)); |
| 4327 |
| 4328 EmitCallJSRuntimeFunction(call); |
| 4329 |
| 4330 // Restore context register. |
| 4331 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4332 context()->DropAndPlug(1, x0); |
| 4333 |
| 4334 EmitInitializeThisAfterSuper(super_reference); |
| 4335 } |
| 4336 |
| 4337 |
| 4338 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4339 // Push the builtins object as the receiver. |
| 4340 __ Ldr(x10, GlobalObjectMemOperand()); |
| 4341 __ Ldr(LoadDescriptor::ReceiverRegister(), |
| 4342 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); |
| 4343 __ Push(LoadDescriptor::ReceiverRegister()); |
| 4344 |
| 4345 // Load the function from the receiver. |
| 4346 Handle<String> name = expr->name(); |
| 4347 __ Mov(LoadDescriptor::NameRegister(), Operand(name)); |
| 4348 if (FLAG_vector_ics) { |
| 4349 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
| 4350 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); |
| 4351 CallLoadIC(NOT_CONTEXTUAL); |
| 4352 } else { |
| 4353 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
| 4354 } |
| 4355 } |
| 4356 |
| 4357 |
| 4358 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4359 ZoneList<Expression*>* args = expr->arguments(); |
| 4360 int arg_count = args->length(); |
| 4361 |
| 4362 // Record source position of the IC call. |
| 4363 SetSourcePosition(expr->position()); |
| 4364 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4365 __ Peek(x1, (arg_count + 1) * kPointerSize); |
| 4366 __ CallStub(&stub); |
| 4367 } |
| 4368 |
| 4369 |
4297 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4370 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4298 ZoneList<Expression*>* args = expr->arguments(); | 4371 ZoneList<Expression*>* args = expr->arguments(); |
4299 int arg_count = args->length(); | 4372 int arg_count = args->length(); |
4300 | 4373 |
4301 if (expr->is_jsruntime()) { | 4374 if (expr->is_jsruntime()) { |
4302 Comment cmnt(masm_, "[ CallRunTime"); | 4375 Comment cmnt(masm_, "[ CallRunTime"); |
4303 // Push the builtins object as the receiver. | 4376 EmitLoadJSRuntimeFunction(expr); |
4304 __ Ldr(x10, GlobalObjectMemOperand()); | |
4305 __ Ldr(LoadDescriptor::ReceiverRegister(), | |
4306 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); | |
4307 __ Push(LoadDescriptor::ReceiverRegister()); | |
4308 | |
4309 // Load the function from the receiver. | |
4310 Handle<String> name = expr->name(); | |
4311 __ Mov(LoadDescriptor::NameRegister(), Operand(name)); | |
4312 if (FLAG_vector_ics) { | |
4313 __ Mov(VectorLoadICDescriptor::SlotRegister(), | |
4314 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); | |
4315 CallLoadIC(NOT_CONTEXTUAL); | |
4316 } else { | |
4317 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | |
4318 } | |
4319 | 4377 |
4320 // Push the target function under the receiver. | 4378 // Push the target function under the receiver. |
4321 __ Pop(x10); | 4379 __ Pop(x10); |
4322 __ Push(x0, x10); | 4380 __ Push(x0, x10); |
4323 | 4381 |
4324 for (int i = 0; i < arg_count; i++) { | 4382 for (int i = 0; i < arg_count; i++) { |
4325 VisitForStackValue(args->at(i)); | 4383 VisitForStackValue(args->at(i)); |
4326 } | 4384 } |
4327 | 4385 |
4328 // Record source position of the IC call. | 4386 EmitCallJSRuntimeFunction(expr); |
4329 SetSourcePosition(expr->position()); | |
4330 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | |
4331 __ Peek(x1, (arg_count + 1) * kPointerSize); | |
4332 __ CallStub(&stub); | |
4333 | 4387 |
4334 // Restore context register. | 4388 // Restore context register. |
4335 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4389 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4336 | 4390 |
4337 context()->DropAndPlug(1, x0); | 4391 context()->DropAndPlug(1, x0); |
4338 | 4392 |
4339 } else { | 4393 } else { |
4340 const Runtime::Function* function = expr->function(); | 4394 const Runtime::Function* function = expr->function(); |
4341 switch (function->function_id) { | 4395 switch (function->function_id) { |
4342 #define CALL_INTRINSIC_GENERATOR(Name) \ | 4396 #define CALL_INTRINSIC_GENERATOR(Name) \ |
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5454 } | 5508 } |
5455 } | 5509 } |
5456 | 5510 |
5457 return INTERRUPT; | 5511 return INTERRUPT; |
5458 } | 5512 } |
5459 | 5513 |
5460 | 5514 |
5461 } } // namespace v8::internal | 5515 } } // namespace v8::internal |
5462 | 5516 |
5463 #endif // V8_TARGET_ARCH_ARM64 | 5517 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |