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

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

Issue 1468073004: Reshuffle registers in JSConstructStub to avoid trashing costructor and new.target on fast path (so… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.cc » ('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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698