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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 354 |
355 // Preserve the four incoming parameters on the stack. | 355 // Preserve the four incoming parameters on the stack. |
356 Register argc = x0; | 356 Register argc = x0; |
357 Register constructor = x1; | 357 Register constructor = x1; |
358 Register allocation_site = x2; | 358 Register allocation_site = x2; |
359 Register new_target = x3; | 359 Register new_target = x3; |
360 | 360 |
361 // Preserve the incoming parameters on the stack. | 361 // Preserve the incoming parameters on the stack. |
362 __ AssertUndefinedOrAllocationSite(allocation_site, x10); | 362 __ AssertUndefinedOrAllocationSite(allocation_site, x10); |
363 __ SmiTag(argc); | 363 __ SmiTag(argc); |
364 if (create_implicit_receiver) { | 364 __ Push(allocation_site, argc); |
365 __ Push(allocation_site, argc, constructor, new_target); | |
366 } else { | |
367 __ Push(allocation_site, argc); | |
368 } | |
369 | 365 |
370 if (create_implicit_receiver) { | 366 if (create_implicit_receiver) { |
371 // sp[0]: new.target | 367 // sp[0]: new.target |
372 // sp[1]: Constructor function. | 368 // sp[1]: Constructor function. |
373 // sp[2]: number of arguments (smi-tagged) | 369 // sp[2]: number of arguments (smi-tagged) |
374 // sp[3]: allocation site | 370 // sp[3]: allocation site |
375 // Try to allocate the object without transitioning into C code. If any of | 371 // Try to allocate the object without transitioning into C code. If any of |
376 // the preconditions is not met, the code bails out to the runtime call. | 372 // the preconditions is not met, the code bails out to the runtime call. |
377 Label rt_call, allocated; | 373 Label rt_call, allocated; |
378 if (FLAG_inline_new) { | 374 if (FLAG_inline_new) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 __ Ldr(x4, bit_field3); | 407 __ Ldr(x4, bit_field3); |
412 __ DecodeField<Map::Counter>(constructon_count, x4); | 408 __ DecodeField<Map::Counter>(constructon_count, x4); |
413 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 409 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
414 __ B(lt, &allocate); | 410 __ B(lt, &allocate); |
415 // Decrease generous allocation count. | 411 // Decrease generous allocation count. |
416 __ Subs(x4, x4, Operand(1 << Map::Counter::kShift)); | 412 __ Subs(x4, x4, Operand(1 << Map::Counter::kShift)); |
417 __ Str(x4, bit_field3); | 413 __ Str(x4, bit_field3); |
418 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 414 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
419 __ B(ne, &allocate); | 415 __ B(ne, &allocate); |
420 | 416 |
421 // Push the constructor and map to the stack, and the map again | 417 // Push the constructor, new_target and map to the stack, and |
422 // as argument to the runtime call. | 418 // the map again as an argument to the runtime call. |
423 __ Push(constructor, init_map, init_map); | 419 __ Push(constructor, new_target, init_map, init_map); |
424 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | 420 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); |
425 __ Pop(init_map, constructor); | 421 __ Pop(init_map, new_target, constructor); |
426 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); | 422 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); |
427 __ Bind(&allocate); | 423 __ Bind(&allocate); |
428 } | 424 } |
429 | 425 |
430 // Now allocate the JSObject on the heap. | 426 // Now allocate the JSObject on the heap. |
431 Label rt_call_reload_new_target; | 427 Register obj_size = x10; |
432 Register obj_size = x3; | |
433 Register new_obj = x4; | 428 Register new_obj = x4; |
434 Register next_obj = x10; | 429 Register next_obj = obj_size; // May overlap. |
435 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 430 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
436 __ Allocate(obj_size, new_obj, next_obj, x11, | 431 __ Allocate(obj_size, new_obj, next_obj, x11, &rt_call, SIZE_IN_WORDS); |
437 &rt_call_reload_new_target, SIZE_IN_WORDS); | |
438 | 432 |
439 // Allocated the JSObject, now initialize the fields. Map is set to | 433 // Allocated the JSObject, now initialize the fields. Map is set to |
440 // initial map and properties and elements are set to empty fixed array. | 434 // initial map and properties and elements are set to empty fixed array. |
441 // NB. the object pointer is not tagged, so MemOperand is used. | 435 // NB. the object pointer is not tagged, so MemOperand is used. |
442 Register write_address = x5; | 436 Register write_address = x5; |
443 Register empty = x7; | 437 Register empty = x7; |
444 __ Mov(write_address, new_obj); | 438 __ Mov(write_address, new_obj); |
445 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 439 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
446 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); | 440 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); |
447 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex)); | 441 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex)); |
448 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); | 442 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); |
449 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); | 443 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); |
450 __ Stp(empty, empty, | 444 __ Stp(empty, empty, |
451 MemOperand(write_address, 2 * kPointerSize, PostIndex)); | 445 MemOperand(write_address, 2 * kPointerSize, PostIndex)); |
| 446 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); |
452 | 447 |
453 // Fill all of the in-object properties with the appropriate filler. | 448 // Fill all of the in-object properties with the appropriate filler. |
454 Register filler = x7; | 449 Register filler = x7; |
455 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); | 450 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); |
456 | 451 |
457 if (!is_api_function) { | 452 if (!is_api_function) { |
458 Label no_inobject_slack_tracking; | 453 Label no_inobject_slack_tracking; |
459 | 454 |
460 // Check if slack tracking is enabled. | 455 // Check if slack tracking is enabled. |
461 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 456 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
(...skipping 29 matching lines...) Expand all Loading... |
491 | 486 |
492 // Fill all of the property fields with undef. | 487 // Fill all of the property fields with undef. |
493 __ InitializeFieldsWithFiller(write_address, next_obj, filler); | 488 __ InitializeFieldsWithFiller(write_address, next_obj, filler); |
494 | 489 |
495 // Add the object tag to make the JSObject real, so that we can continue | 490 // Add the object tag to make the JSObject real, so that we can continue |
496 // and jump into the continuation code at any time from now on. | 491 // and jump into the continuation code at any time from now on. |
497 __ Add(new_obj, new_obj, kHeapObjectTag); | 492 __ Add(new_obj, new_obj, kHeapObjectTag); |
498 | 493 |
499 // Continue with JSObject being successfully allocated. | 494 // Continue with JSObject being successfully allocated. |
500 __ B(&allocated); | 495 __ B(&allocated); |
501 | |
502 // Reload the new target and fall-through. | |
503 __ Bind(&rt_call_reload_new_target); | |
504 __ Peek(x3, 0 * kXRegSize); | |
505 } | 496 } |
506 | 497 |
507 // Allocate the new receiver object using the runtime call. | 498 // Allocate the new receiver object using the runtime call. |
508 // x1: constructor function | 499 // x1: constructor function |
509 // x3: new target | 500 // x3: new target |
510 __ Bind(&rt_call); | 501 __ Bind(&rt_call); |
511 __ Push(constructor, new_target); // arguments 1-2 | 502 |
| 503 // Push the constructor and new_target twice, second pair as arguments |
| 504 // to the runtime call. |
| 505 __ Push(constructor, new_target, constructor, new_target); |
512 __ CallRuntime(Runtime::kNewObject, 2); | 506 __ CallRuntime(Runtime::kNewObject, 2); |
513 __ Mov(x4, x0); | 507 __ Mov(x4, x0); |
| 508 __ Pop(new_target, constructor); |
514 | 509 |
515 // Receiver for constructor call allocated. | 510 // Receiver for constructor call allocated. |
| 511 // x1: constructor function |
| 512 // x3: new target |
516 // x4: JSObject | 513 // x4: JSObject |
517 __ Bind(&allocated); | 514 __ Bind(&allocated); |
518 | 515 |
519 // Restore the parameters. | |
520 __ Pop(new_target); | |
521 __ Pop(constructor); | |
522 | |
523 // Reload the number of arguments from the stack. | 516 // Reload the number of arguments from the stack. |
524 // Set it up in x0 for the function call below. | 517 // Set it up in x0 for the function call below. |
525 // jssp[0]: number of arguments (smi-tagged) | 518 // jssp[0]: number of arguments (smi-tagged) |
526 __ Peek(argc, 0); // Load number of arguments. | 519 __ Peek(argc, 0); // Load number of arguments. |
527 } | 520 } |
528 | 521 |
529 __ SmiUntag(argc); | 522 __ SmiUntag(argc); |
530 | 523 |
531 // Push new.target onto the construct frame. This is stored just below the | 524 // Push new.target onto the construct frame. This is stored just below the |
532 // receiver on the stack. | 525 // receiver on the stack. |
(...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 } | 1917 } |
1925 } | 1918 } |
1926 | 1919 |
1927 | 1920 |
1928 #undef __ | 1921 #undef __ |
1929 | 1922 |
1930 } // namespace internal | 1923 } // namespace internal |
1931 } // namespace v8 | 1924 } // namespace v8 |
1932 | 1925 |
1933 #endif // V8_TARGET_ARCH_ARM | 1926 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |