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/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 __ B(hs, &ok); | 294 __ B(hs, &ok); |
295 | 295 |
296 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 296 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); |
297 GenerateTailCallToReturnedCode(masm); | 297 GenerateTailCallToReturnedCode(masm); |
298 | 298 |
299 __ Bind(&ok); | 299 __ Bind(&ok); |
300 GenerateTailCallToSharedCode(masm); | 300 GenerateTailCallToSharedCode(masm); |
301 } | 301 } |
302 | 302 |
303 | 303 |
| 304 static void Generate_Runtime_NewObject(MacroAssembler* masm, |
| 305 bool create_memento, |
| 306 Register original_constructor, |
| 307 Label* count_incremented, |
| 308 Label* allocated) { |
| 309 if (create_memento) { |
| 310 // Get the cell or allocation site. |
| 311 __ Peek(x4, 2 * kXRegSize); |
| 312 __ Push(x4); |
| 313 __ Push(x1); // Argument for Runtime_NewObject. |
| 314 __ Push(original_constructor); |
| 315 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); |
| 316 __ Mov(x4, x0); |
| 317 // If we ended up using the runtime, and we want a memento, then the |
| 318 // runtime call made it for us, and we shouldn't do create count |
| 319 // increment. |
| 320 __ jmp(count_incremented); |
| 321 } else { |
| 322 __ Push(x1); // Argument for Runtime_NewObject. |
| 323 __ Push(original_constructor); |
| 324 __ CallRuntime(Runtime::kNewObject, 2); |
| 325 __ Mov(x4, x0); |
| 326 __ jmp(allocated); |
| 327 } |
| 328 } |
| 329 |
| 330 |
304 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 331 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
305 bool is_api_function, | 332 bool is_api_function, |
306 bool create_memento) { | 333 bool create_memento) { |
307 // ----------- S t a t e ------------- | 334 // ----------- S t a t e ------------- |
308 // -- x0 : number of arguments | 335 // -- x0 : number of arguments |
309 // -- x1 : constructor function | 336 // -- x1 : constructor function |
310 // -- x2 : allocation site or undefined | 337 // -- x2 : allocation site or undefined |
| 338 // -- x3 : original constructor |
311 // -- lr : return address | 339 // -- lr : return address |
312 // -- sp[...]: constructor arguments | 340 // -- sp[...]: constructor arguments |
313 // ----------------------------------- | 341 // ----------------------------------- |
314 | 342 |
315 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); | 343 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); |
316 // Should never create mementos for api functions. | 344 // Should never create mementos for api functions. |
317 DCHECK(!is_api_function || !create_memento); | 345 DCHECK(!is_api_function || !create_memento); |
318 | 346 |
319 Isolate* isolate = masm->isolate(); | 347 Isolate* isolate = masm->isolate(); |
320 | 348 |
321 // Enter a construct frame. | 349 // Enter a construct frame. |
322 { | 350 { |
323 FrameScope scope(masm, StackFrame::CONSTRUCT); | 351 FrameScope scope(masm, StackFrame::CONSTRUCT); |
324 | 352 |
325 // Preserve the three incoming parameters on the stack. | 353 // Preserve the three incoming parameters on the stack. |
326 if (create_memento) { | 354 if (create_memento) { |
327 __ AssertUndefinedOrAllocationSite(x2, x10); | 355 __ AssertUndefinedOrAllocationSite(x2, x10); |
328 __ Push(x2); | 356 __ Push(x2); |
329 } | 357 } |
330 | 358 |
331 Register argc = x0; | 359 Register argc = x0; |
332 Register constructor = x1; | 360 Register constructor = x1; |
| 361 Register original_constructor = x3; |
333 // x1: constructor function | 362 // x1: constructor function |
334 __ SmiTag(argc); | 363 __ SmiTag(argc); |
335 __ Push(argc, constructor); | 364 __ Push(argc, constructor); |
336 // sp[0] : Constructor function. | 365 // sp[0] : Constructor function. |
337 // sp[1]: number of arguments (smi-tagged) | 366 // sp[1]: number of arguments (smi-tagged) |
338 | 367 |
| 368 Label rt_call, count_incremented, allocated, normal_new; |
| 369 __ Cmp(constructor, original_constructor); |
| 370 __ B(eq, &normal_new); |
| 371 Generate_Runtime_NewObject(masm, create_memento, original_constructor, |
| 372 &count_incremented, &allocated); |
| 373 |
| 374 __ Bind(&normal_new); |
| 375 |
339 // Try to allocate the object without transitioning into C code. If any of | 376 // Try to allocate the object without transitioning into C code. If any of |
340 // the preconditions is not met, the code bails out to the runtime call. | 377 // the preconditions is not met, the code bails out to the runtime call. |
341 Label rt_call, allocated; | |
342 if (FLAG_inline_new) { | 378 if (FLAG_inline_new) { |
343 Label undo_allocation; | 379 Label undo_allocation; |
344 ExternalReference debug_step_in_fp = | 380 ExternalReference debug_step_in_fp = |
345 ExternalReference::debug_step_in_fp_address(isolate); | 381 ExternalReference::debug_step_in_fp_address(isolate); |
346 __ Mov(x2, Operand(debug_step_in_fp)); | 382 __ Mov(x2, Operand(debug_step_in_fp)); |
347 __ Ldr(x2, MemOperand(x2)); | 383 __ Ldr(x2, MemOperand(x2)); |
348 __ Cbnz(x2, &rt_call); | 384 __ Cbnz(x2, &rt_call); |
349 // Load the initial map and verify that it is in fact a map. | 385 // Load the initial map and verify that it is in fact a map. |
350 Register init_map = x2; | 386 Register init_map = x2; |
351 __ Ldr(init_map, | 387 __ Ldr(init_map, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 | 564 |
529 // Undo the setting of the new top so that the heap is verifiable. For | 565 // Undo the setting of the new top so that the heap is verifiable. For |
530 // example, the map's unused properties potentially do not match the | 566 // example, the map's unused properties potentially do not match the |
531 // allocated objects unused properties. | 567 // allocated objects unused properties. |
532 __ Bind(&undo_allocation); | 568 __ Bind(&undo_allocation); |
533 __ UndoAllocationInNewSpace(new_obj, x14); | 569 __ UndoAllocationInNewSpace(new_obj, x14); |
534 } | 570 } |
535 | 571 |
536 // Allocate the new receiver object using the runtime call. | 572 // Allocate the new receiver object using the runtime call. |
537 __ Bind(&rt_call); | 573 __ Bind(&rt_call); |
538 Label count_incremented; | 574 Generate_Runtime_NewObject(masm, create_memento, constructor, |
539 if (create_memento) { | 575 &count_incremented, &allocated); |
540 // Get the cell or allocation site. | |
541 __ Peek(x4, 2 * kXRegSize); | |
542 __ Push(x4); | |
543 __ Push(constructor); // Argument for Runtime_NewObject. | |
544 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); | |
545 __ Mov(x4, x0); | |
546 // If we ended up using the runtime, and we want a memento, then the | |
547 // runtime call made it for us, and we shouldn't do create count | |
548 // increment. | |
549 __ jmp(&count_incremented); | |
550 } else { | |
551 __ Push(constructor); // Argument for Runtime_NewObject. | |
552 __ CallRuntime(Runtime::kNewObject, 1); | |
553 __ Mov(x4, x0); | |
554 } | |
555 | 576 |
556 // Receiver for constructor call allocated. | 577 // Receiver for constructor call allocated. |
557 // x4: JSObject | 578 // x4: JSObject |
558 __ Bind(&allocated); | 579 __ Bind(&allocated); |
559 | 580 |
560 if (create_memento) { | 581 if (create_memento) { |
561 __ Peek(x10, 2 * kXRegSize); | 582 __ Peek(x10, 2 * kXRegSize); |
562 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | 583 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); |
563 // r2 is an AllocationSite. We are creating a memento from it, so we | 584 // r2 is an AllocationSite. We are creating a memento from it, so we |
564 // need to increment the memento create count. | 585 // need to increment the memento create count. |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 __ Unreachable(); | 1576 __ Unreachable(); |
1556 } | 1577 } |
1557 } | 1578 } |
1558 | 1579 |
1559 | 1580 |
1560 #undef __ | 1581 #undef __ |
1561 | 1582 |
1562 } } // namespace v8::internal | 1583 } } // namespace v8::internal |
1563 | 1584 |
1564 #endif // V8_TARGET_ARCH_ARM | 1585 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |