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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 __ Cmp(constructor, x10); | 387 __ Cmp(constructor, x10); |
388 __ B(ne, &rt_call); | 388 __ B(ne, &rt_call); |
389 | 389 |
390 // Check that the constructor is not constructing a JSFunction (see | 390 // Check that the constructor is not constructing a JSFunction (see |
391 // comments in Runtime_NewObject in runtime.cc). In which case the | 391 // comments in Runtime_NewObject in runtime.cc). In which case the |
392 // initial | 392 // initial |
393 // map's instance type would be JS_FUNCTION_TYPE. | 393 // map's instance type would be JS_FUNCTION_TYPE. |
394 __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE); | 394 __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE); |
395 __ B(eq, &rt_call); | 395 __ B(eq, &rt_call); |
396 | 396 |
397 Register constructon_count = x14; | |
398 if (!is_api_function) { | |
399 Label allocate; | |
400 MemOperand bit_field3 = | |
401 FieldMemOperand(init_map, Map::kBitField3Offset); | |
402 // Check if slack tracking is enabled. | |
403 __ Ldr(x4, bit_field3); | |
404 __ DecodeField<Map::Counter>(constructon_count, x4); | |
405 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | |
406 __ B(lt, &allocate); | |
407 // Decrease generous allocation count. | |
408 __ Subs(x4, x4, Operand(1 << Map::Counter::kShift)); | |
409 __ Str(x4, bit_field3); | |
410 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | |
411 __ B(ne, &allocate); | |
412 | |
413 // Push the constructor, new_target and map to the stack, and | |
414 // the map again as an argument to the runtime call. | |
415 __ Push(constructor, new_target, init_map, init_map); | |
416 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | |
417 __ Pop(init_map, new_target, constructor); | |
418 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); | |
419 __ Bind(&allocate); | |
420 } | |
421 | |
422 // Now allocate the JSObject on the heap. | 397 // Now allocate the JSObject on the heap. |
423 Register obj_size = x10; | 398 Register obj_size = x10; |
424 Register new_obj = x4; | 399 Register new_obj = x4; |
425 Register next_obj = obj_size; // May overlap. | 400 Register next_obj = obj_size; // May overlap. |
426 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 401 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
427 __ Allocate(obj_size, new_obj, next_obj, x11, &rt_call, SIZE_IN_WORDS); | 402 __ Allocate(obj_size, new_obj, next_obj, x11, &rt_call, SIZE_IN_WORDS); |
428 | 403 |
429 // Allocated the JSObject, now initialize the fields. Map is set to | 404 // Allocated the JSObject, now initialize the fields. Map is set to |
430 // initial map and properties and elements are set to empty fixed array. | 405 // initial map and properties and elements are set to empty fixed array. |
431 // NB. the object pointer is not tagged, so MemOperand is used. | 406 // NB. the object pointer is not tagged, so MemOperand is used. |
432 Register write_address = x5; | 407 Register write_address = x5; |
433 Register empty = x7; | 408 Register empty = x7; |
434 __ Mov(write_address, new_obj); | 409 __ Mov(write_address, new_obj); |
435 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 410 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
436 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); | 411 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); |
437 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex)); | 412 __ Str(init_map, MemOperand(write_address, kPointerSize, PostIndex)); |
438 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); | 413 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); |
439 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); | 414 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); |
440 __ Stp(empty, empty, | 415 __ Stp(empty, empty, |
441 MemOperand(write_address, 2 * kPointerSize, PostIndex)); | 416 MemOperand(write_address, 2 * kPointerSize, PostIndex)); |
442 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); | 417 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize); |
443 | 418 |
| 419 // Add the object tag to make the JSObject real, so that we can continue |
| 420 // and jump into the continuation code at any time from now on. |
| 421 __ Add(new_obj, new_obj, kHeapObjectTag); |
| 422 |
444 // Fill all of the in-object properties with the appropriate filler. | 423 // Fill all of the in-object properties with the appropriate filler. |
445 Register filler = x7; | 424 Register filler = x7; |
446 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); | 425 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex); |
447 | 426 |
448 if (!is_api_function) { | 427 if (!is_api_function) { |
449 Label no_inobject_slack_tracking; | 428 Label no_inobject_slack_tracking; |
450 | 429 |
| 430 Register constructon_count = x14; |
| 431 MemOperand bit_field3 = |
| 432 FieldMemOperand(init_map, Map::kBitField3Offset); |
451 // Check if slack tracking is enabled. | 433 // Check if slack tracking is enabled. |
| 434 __ Ldr(x11, bit_field3); |
| 435 __ DecodeField<Map::Counter>(constructon_count, x11); |
452 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); | 436 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
453 __ B(lt, &no_inobject_slack_tracking); | 437 __ B(lt, &no_inobject_slack_tracking); |
454 constructon_count = NoReg; | 438 // Decrease generous allocation count. |
| 439 __ Subs(x11, x11, Operand(1 << Map::Counter::kShift)); |
| 440 __ Str(x11, bit_field3); |
455 | 441 |
456 // Allocate object with a slack. | 442 // Allocate object with a slack. |
457 Register unused_props = x11; | 443 Register unused_props = x11; |
458 __ Ldr(unused_props, | 444 __ Ldr(unused_props, |
459 FieldMemOperand(init_map, Map::kInstanceAttributesOffset)); | 445 FieldMemOperand(init_map, Map::kInstanceAttributesOffset)); |
460 __ Ubfx(unused_props, unused_props, | 446 __ Ubfx(unused_props, unused_props, |
461 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte); | 447 Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte); |
462 | 448 |
463 Register end_of_pre_allocated = x11; | 449 Register end_of_pre_allocated = x11; |
464 __ Sub(end_of_pre_allocated, next_obj, | 450 __ Sub(end_of_pre_allocated, next_obj, |
465 Operand(unused_props, LSL, kPointerSizeLog2)); | 451 Operand(unused_props, LSL, kPointerSizeLog2)); |
466 unused_props = NoReg; | 452 unused_props = NoReg; |
467 | 453 |
468 if (FLAG_debug_code) { | 454 if (FLAG_debug_code) { |
469 __ Cmp(write_address, end_of_pre_allocated); | 455 __ Cmp(write_address, end_of_pre_allocated); |
470 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | 456 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); |
471 } | 457 } |
472 | 458 |
473 // Fill the pre-allocated fields with undef. | 459 // Fill the pre-allocated fields with undef. |
474 __ InitializeFieldsWithFiller(write_address, end_of_pre_allocated, | 460 __ InitializeFieldsWithFiller(write_address, end_of_pre_allocated, |
475 filler); | 461 filler); |
476 | 462 |
477 // Fill the remaining fields with one pointer filler map. | 463 // Fill the remaining fields with one pointer filler map. |
478 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); | 464 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); |
| 465 __ InitializeFieldsWithFiller(write_address, next_obj, filler); |
| 466 |
| 467 __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd)); |
| 468 __ B(ne, &allocated); |
| 469 |
| 470 // Push the constructor, new_target and the object to the stack, |
| 471 // and then the initial map as an argument to the runtime call. |
| 472 __ Push(constructor, new_target, new_obj, init_map); |
| 473 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); |
| 474 __ Pop(new_obj, new_target, constructor); |
| 475 |
| 476 // Continue with JSObject being successfully allocated. |
| 477 __ B(&allocated); |
479 | 478 |
480 __ bind(&no_inobject_slack_tracking); | 479 __ bind(&no_inobject_slack_tracking); |
481 } | 480 } |
482 | 481 |
483 // Fill all of the property fields with undef. | |
484 __ InitializeFieldsWithFiller(write_address, next_obj, filler); | 482 __ InitializeFieldsWithFiller(write_address, next_obj, filler); |
485 | 483 |
486 // Add the object tag to make the JSObject real, so that we can continue | |
487 // and jump into the continuation code at any time from now on. | |
488 __ Add(new_obj, new_obj, kHeapObjectTag); | |
489 | |
490 // Continue with JSObject being successfully allocated. | 484 // Continue with JSObject being successfully allocated. |
491 __ B(&allocated); | 485 __ B(&allocated); |
492 } | 486 } |
493 | 487 |
494 // Allocate the new receiver object using the runtime call. | 488 // Allocate the new receiver object using the runtime call. |
495 // x1: constructor function | 489 // x1: constructor function |
496 // x3: new target | 490 // x3: new target |
497 __ Bind(&rt_call); | 491 __ Bind(&rt_call); |
498 | 492 |
499 // Push the constructor and new_target twice, second pair as arguments | 493 // Push the constructor and new_target twice, second pair as arguments |
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2043 } | 2037 } |
2044 } | 2038 } |
2045 | 2039 |
2046 | 2040 |
2047 #undef __ | 2041 #undef __ |
2048 | 2042 |
2049 } // namespace internal | 2043 } // namespace internal |
2050 } // namespace v8 | 2044 } // namespace v8 |
2051 | 2045 |
2052 #endif // V8_TARGET_ARCH_ARM | 2046 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |