Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: src/arm64/builtins-arm64.cc

Issue 1488023002: Fix inobject slack tracking for both subclassing and non-subclassing cases. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moved and updated comments about slack tracking Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698