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