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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 // derived constructors with super calls. | 243 // derived constructors with super calls. |
244 Variable* this_function_var = scope()->this_function_var(); | 244 Variable* this_function_var = scope()->this_function_var(); |
245 if (this_function_var != nullptr) { | 245 if (this_function_var != nullptr) { |
246 Comment cmnt(masm_, "[ This function"); | 246 Comment cmnt(masm_, "[ This function"); |
247 SetVar(this_function_var, x1, x0, x2); | 247 SetVar(this_function_var, x1, x0, x2); |
248 } | 248 } |
249 | 249 |
250 Variable* new_target_var = scope()->new_target_var(); | 250 Variable* new_target_var = scope()->new_target_var(); |
251 if (new_target_var != nullptr) { | 251 if (new_target_var != nullptr) { |
252 Comment cmnt(masm_, "[ new.target"); | 252 Comment cmnt(masm_, "[ new.target"); |
| 253 // Get the frame pointer for the calling frame. |
| 254 __ Ldr(x2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 255 |
| 256 Label check_frame_marker; |
| 257 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kContextOffset)); |
| 258 __ Cmp(x1, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 259 __ B(ne, &check_frame_marker); |
| 260 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
| 261 __ Bind(&check_frame_marker); |
| 262 __ Ldr(x1, MemOperand(x2, StandardFrameConstants::kMarkerOffset)); |
| 263 __ Cmp(x1, Smi::FromInt(StackFrame::CONSTRUCT)); |
| 264 |
| 265 Label non_construct_frame, done; |
| 266 |
| 267 __ B(ne, &non_construct_frame); |
| 268 __ Ldr(x0, MemOperand(x2, StandardFrameConstants::kExpressionsOffset - |
| 269 2 * kPointerSize)); |
| 270 __ B(&done); |
| 271 |
| 272 __ Bind(&non_construct_frame); |
| 273 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
| 274 |
| 275 __ Bind(&done); |
253 // new.target is parameter -2. | 276 // new.target is parameter -2. |
254 int offset = | |
255 2 * kXRegSize + (info_->scope()->num_parameters() + 1) * kPointerSize; | |
256 __ Ldr(x0, MemOperand(fp, offset)); | |
257 SetVar(new_target_var, x0, x2, x3); | 277 SetVar(new_target_var, x0, x2, x3); |
258 } | 278 } |
259 | 279 |
260 ArgumentsAccessStub::HasNewTarget has_new_target = | |
261 IsSubclassConstructor(info->function()->kind()) | |
262 ? ArgumentsAccessStub::HAS_NEW_TARGET | |
263 : ArgumentsAccessStub::NO_NEW_TARGET; | |
264 | |
265 // Possibly allocate RestParameters | 280 // Possibly allocate RestParameters |
266 int rest_index; | 281 int rest_index; |
267 Variable* rest_param = scope()->rest_parameter(&rest_index); | 282 Variable* rest_param = scope()->rest_parameter(&rest_index); |
268 if (rest_param) { | 283 if (rest_param) { |
269 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 284 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
270 | 285 |
271 int num_parameters = info->scope()->num_parameters(); | 286 int num_parameters = info->scope()->num_parameters(); |
272 int offset = num_parameters * kPointerSize; | 287 int offset = num_parameters * kPointerSize; |
273 if (has_new_target == ArgumentsAccessStub::HAS_NEW_TARGET) { | |
274 --num_parameters; | |
275 ++rest_index; | |
276 } | |
277 | 288 |
278 __ Add(x3, fp, StandardFrameConstants::kCallerSPOffset + offset); | 289 __ Add(x3, fp, StandardFrameConstants::kCallerSPOffset + offset); |
279 __ Mov(x2, Smi::FromInt(num_parameters)); | 290 __ Mov(x2, Smi::FromInt(num_parameters)); |
280 __ Mov(x1, Smi::FromInt(rest_index)); | 291 __ Mov(x1, Smi::FromInt(rest_index)); |
281 __ Mov(x0, Smi::FromInt(language_mode())); | 292 __ Mov(x0, Smi::FromInt(language_mode())); |
282 __ Push(x3, x2, x1, x0); | 293 __ Push(x3, x2, x1, x0); |
283 | 294 |
284 RestParamAccessStub stub(isolate()); | 295 RestParamAccessStub stub(isolate()); |
285 __ CallStub(&stub); | 296 __ CallStub(&stub); |
286 | 297 |
(...skipping 22 matching lines...) Expand all Loading... |
309 // The stub will rewrite receiver and parameter count if the previous | 320 // The stub will rewrite receiver and parameter count if the previous |
310 // stack frame was an arguments adapter frame. | 321 // stack frame was an arguments adapter frame. |
311 ArgumentsAccessStub::Type type; | 322 ArgumentsAccessStub::Type type; |
312 if (is_strict(language_mode()) || !is_simple_parameter_list()) { | 323 if (is_strict(language_mode()) || !is_simple_parameter_list()) { |
313 type = ArgumentsAccessStub::NEW_STRICT; | 324 type = ArgumentsAccessStub::NEW_STRICT; |
314 } else if (function()->has_duplicate_parameters()) { | 325 } else if (function()->has_duplicate_parameters()) { |
315 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 326 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
316 } else { | 327 } else { |
317 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 328 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
318 } | 329 } |
319 ArgumentsAccessStub stub(isolate(), type, has_new_target); | 330 ArgumentsAccessStub stub(isolate(), type); |
320 __ CallStub(&stub); | 331 __ CallStub(&stub); |
321 | 332 |
322 SetVar(arguments, x0, x1, x2); | 333 SetVar(arguments, x0, x1, x2); |
323 } | 334 } |
324 | 335 |
325 if (FLAG_trace) { | 336 if (FLAG_trace) { |
326 __ CallRuntime(Runtime::kTraceEnter, 0); | 337 __ CallRuntime(Runtime::kTraceEnter, 0); |
327 } | 338 } |
328 | 339 |
329 // Visit the declarations and body unless there is an illegal | 340 // Visit the declarations and body unless there is an illegal |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 int no_frame_start = masm_->pc_offset(); | 506 int no_frame_start = masm_->pc_offset(); |
496 __ ldp(fp, lr, MemOperand(current_sp, 2 * kXRegSize, PostIndex)); | 507 __ ldp(fp, lr, MemOperand(current_sp, 2 * kXRegSize, PostIndex)); |
497 // Drop the arguments and receiver and return. | 508 // Drop the arguments and receiver and return. |
498 // TODO(all): This implementation is overkill as it supports 2**31+1 | 509 // TODO(all): This implementation is overkill as it supports 2**31+1 |
499 // arguments, consider how to improve it without creating a security | 510 // arguments, consider how to improve it without creating a security |
500 // hole. | 511 // hole. |
501 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); | 512 __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2); |
502 __ add(current_sp, current_sp, ip0); | 513 __ add(current_sp, current_sp, ip0); |
503 __ ret(); | 514 __ ret(); |
504 int32_t arg_count = info_->scope()->num_parameters() + 1; | 515 int32_t arg_count = info_->scope()->num_parameters() + 1; |
505 if (IsSubclassConstructor(info_->function()->kind())) { | |
506 arg_count++; | |
507 } | |
508 __ dc64(kXRegSize * arg_count); | 516 __ dc64(kXRegSize * arg_count); |
509 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 517 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
510 } | 518 } |
511 } | 519 } |
512 } | 520 } |
513 | 521 |
514 | 522 |
515 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { | 523 void FullCodeGenerator::EffectContext::Plug(Variable* var) const { |
516 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 524 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
517 } | 525 } |
(...skipping 3463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3981 // default constructor has no arguments, so no adaptor frame means no args. | 3989 // default constructor has no arguments, so no adaptor frame means no args. |
3982 __ Mov(x0, Operand(0)); | 3990 __ Mov(x0, Operand(0)); |
3983 __ B(&args_set_up); | 3991 __ B(&args_set_up); |
3984 | 3992 |
3985 // Copy arguments from adaptor frame. | 3993 // Copy arguments from adaptor frame. |
3986 { | 3994 { |
3987 __ bind(&adaptor_frame); | 3995 __ bind(&adaptor_frame); |
3988 __ Ldr(x1, MemOperand(x11, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 3996 __ Ldr(x1, MemOperand(x11, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
3989 __ SmiUntag(x1, x1); | 3997 __ SmiUntag(x1, x1); |
3990 | 3998 |
3991 // Subtract 1 from arguments count, for new.target. | |
3992 __ Sub(x1, x1, Operand(1)); | |
3993 __ Mov(x0, x1); | 3999 __ Mov(x0, x1); |
3994 | 4000 |
3995 // Get arguments pointer in x11. | 4001 // Get arguments pointer in x11. |
3996 __ Add(x11, x11, Operand(x1, LSL, kPointerSizeLog2)); | 4002 __ Add(x11, x11, Operand(x1, LSL, kPointerSizeLog2)); |
3997 __ Add(x11, x11, StandardFrameConstants::kCallerSPOffset); | 4003 __ Add(x11, x11, StandardFrameConstants::kCallerSPOffset); |
3998 Label loop; | 4004 Label loop; |
3999 __ bind(&loop); | 4005 __ bind(&loop); |
4000 // Pre-decrement x11 with kPointerSize on each iteration. | 4006 // Pre-decrement x11 with kPointerSize on each iteration. |
4001 // Pre-decrement in order to skip receiver. | 4007 // Pre-decrement in order to skip receiver. |
4002 __ Ldr(x10, MemOperand(x11, -kPointerSize, PreIndex)); | 4008 __ Ldr(x10, MemOperand(x11, -kPointerSize, PreIndex)); |
(...skipping 1575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5578 } | 5584 } |
5579 | 5585 |
5580 return INTERRUPT; | 5586 return INTERRUPT; |
5581 } | 5587 } |
5582 | 5588 |
5583 | 5589 |
5584 } // namespace internal | 5590 } // namespace internal |
5585 } // namespace v8 | 5591 } // namespace v8 |
5586 | 5592 |
5587 #endif // V8_TARGET_ARCH_ARM64 | 5593 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |