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

Side by Side Diff: src/mips/builtins-mips.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/ia32/builtins-ia32.cc ('k') | src/mips/code-stubs-mips.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 364
365 Isolate* isolate = masm->isolate(); 365 Isolate* isolate = masm->isolate();
366 366
367 // Enter a construct frame. 367 // Enter a construct frame.
368 { 368 {
369 FrameScope scope(masm, StackFrame::CONSTRUCT); 369 FrameScope scope(masm, StackFrame::CONSTRUCT);
370 370
371 // Preserve the incoming parameters on the stack. 371 // Preserve the incoming parameters on the stack.
372 __ AssertUndefinedOrAllocationSite(a2, t0); 372 __ AssertUndefinedOrAllocationSite(a2, t0);
373 __ SmiTag(a0); 373 __ SmiTag(a0);
374 if (create_implicit_receiver) { 374 __ Push(a2, a0);
375 __ Push(a2, a0, a1, a3);
376 } else {
377 __ Push(a2, a0);
378 }
379 375
380 if (create_implicit_receiver) { 376 if (create_implicit_receiver) {
381 // Try to allocate the object without transitioning into C code. If any of 377 // Try to allocate the object without transitioning into C code. If any of
382 // the preconditions is not met, the code bails out to the runtime call. 378 // the preconditions is not met, the code bails out to the runtime call.
383 Label rt_call, allocated; 379 Label rt_call, allocated;
384 if (FLAG_inline_new) { 380 if (FLAG_inline_new) {
385 // Verify that the new target is a JSFunction. 381 // Verify that the new target is a JSFunction.
386 __ GetObjectType(a3, t1, t0); 382 __ GetObjectType(a3, t1, t0);
387 __ Branch(&rt_call, ne, t0, Operand(JS_FUNCTION_TYPE)); 383 __ Branch(&rt_call, ne, t0, Operand(JS_FUNCTION_TYPE));
388 384
(...skipping 24 matching lines...) Expand all
413 // Check if slack tracking is enabled. 409 // Check if slack tracking is enabled.
414 __ lw(t0, bit_field3); 410 __ lw(t0, bit_field3);
415 __ DecodeField<Map::Counter>(t2, t0); 411 __ DecodeField<Map::Counter>(t2, t0);
416 __ Branch(&allocate, lt, t2, Operand(Map::kSlackTrackingCounterEnd)); 412 __ Branch(&allocate, lt, t2, Operand(Map::kSlackTrackingCounterEnd));
417 // Decrease generous allocation count. 413 // Decrease generous allocation count.
418 __ Subu(t0, t0, Operand(1 << Map::Counter::kShift)); 414 __ Subu(t0, t0, Operand(1 << Map::Counter::kShift));
419 __ Branch(USE_DELAY_SLOT, &allocate, ne, t2, 415 __ Branch(USE_DELAY_SLOT, &allocate, ne, t2,
420 Operand(Map::kSlackTrackingCounterEnd)); 416 Operand(Map::kSlackTrackingCounterEnd));
421 __ sw(t0, bit_field3); // In delay slot. 417 __ sw(t0, bit_field3); // In delay slot.
422 418
423 __ Push(a1, a2, a2); // a2 = Initial map. 419 // Push the constructor, new_target and map to the stack, and
420 // the map again as an argument to the runtime call.
421 __ Push(a1, a3, a2, a2);
424 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 422 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
425 423
426 __ Pop(a1, a2); 424 __ Pop(a1, a3, a2);
427 __ li(t2, Operand(Map::kSlackTrackingCounterEnd - 1)); 425 __ li(t2, Operand(Map::kSlackTrackingCounterEnd - 1));
428 426
429 __ bind(&allocate); 427 __ bind(&allocate);
430 } 428 }
431 429
432 // Now allocate the JSObject on the heap. 430 // Now allocate the JSObject on the heap.
433 // a1: constructor function 431 // a1: constructor function
434 // a2: initial map 432 // a2: initial map
435 Label rt_call_reload_new_target; 433 // a3: new target
436 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset)); 434 // t2: slack tracking counter (non-API function case)
435 __ lbu(t3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
437 436
438 __ Allocate(a3, t4, t3, t6, &rt_call_reload_new_target, SIZE_IN_WORDS); 437 __ Allocate(t3, t4, t3, t6, &rt_call, SIZE_IN_WORDS);
439 438
440 // Allocated the JSObject, now initialize the fields. Map is set to 439 // Allocated the JSObject, now initialize the fields. Map is set to
441 // initial map and properties and elements are set to empty fixed array. 440 // initial map and properties and elements are set to empty fixed array.
442 // a1: constructor function 441 // a1: constructor function
443 // a2: initial map 442 // a2: initial map
444 // a3: object size 443 // a3: new target
445 // t4: JSObject (not tagged) 444 // t4: JSObject (not tagged)
446 // t3: start of next object 445 // t3: start of next object
446 // t2: slack tracking counter (non-API function case)
447 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex); 447 __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
448 __ mov(t5, t4); 448 __ mov(t5, t4);
449 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset); 449 STATIC_ASSERT(0 * kPointerSize == JSObject::kMapOffset);
450 __ sw(a2, MemOperand(t5, JSObject::kMapOffset)); 450 __ sw(a2, MemOperand(t5, JSObject::kMapOffset));
451 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset); 451 STATIC_ASSERT(1 * kPointerSize == JSObject::kPropertiesOffset);
452 __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset)); 452 __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
453 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset); 453 STATIC_ASSERT(2 * kPointerSize == JSObject::kElementsOffset);
454 __ sw(t6, MemOperand(t5, JSObject::kElementsOffset)); 454 __ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
455 STATIC_ASSERT(3 * kPointerSize == JSObject::kHeaderSize);
455 __ Addu(t5, t5, Operand(3 * kPointerSize)); 456 __ Addu(t5, t5, Operand(3 * kPointerSize));
456 457
457 // Fill all the in-object properties with appropriate filler. 458 // Fill all the in-object properties with appropriate filler.
458 // a1: constructor function
459 // a2: initial map
460 // a3: object size (in words)
461 // t4: JSObject (not tagged)
462 // t5: First in-object property of JSObject (not tagged) 459 // t5: First in-object property of JSObject (not tagged)
463 // t2: slack tracking counter (non-API function case)
464 DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize);
465 460
466 // Use t7 to hold undefined, which is used in several places below. 461 // Use t7 to hold undefined, which is used in several places below.
467 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 462 __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
468 463
469 if (!is_api_function) { 464 if (!is_api_function) {
470 Label no_inobject_slack_tracking; 465 Label no_inobject_slack_tracking;
471 466
472 // Check if slack tracking is enabled. 467 // Check if slack tracking is enabled.
473 __ Branch(&no_inobject_slack_tracking, lt, t2, 468 __ Branch(&no_inobject_slack_tracking, lt, t2,
474 Operand(Map::kSlackTrackingCounterEnd)); 469 Operand(Map::kSlackTrackingCounterEnd));
475 470
476 // Allocate object with a slack. 471 // Allocate object with a slack.
477 __ lbu(a0, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset)); 472 __ lbu(a0, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
478 __ sll(a0, a0, kPointerSizeLog2); 473 __ sll(a0, a0, kPointerSizeLog2);
479 __ subu(a0, t3, a0); 474 __ subu(a0, t3, a0);
480 // a0: offset of first field after pre-allocated fields 475 // a0: offset of first field after pre-allocated fields
481 if (FLAG_debug_code) { 476 if (FLAG_debug_code) {
482 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, t5, 477 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, t5,
483 Operand(a0)); 478 Operand(a0));
484 } 479 }
485 __ InitializeFieldsWithFiller(t5, a0, t7); 480 __ InitializeFieldsWithFiller(t5, a0, t7);
486 // To allow for truncation. 481
482 // To allow truncation fill the remaining fields with one pointer
483 // filler map.
487 __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex); 484 __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
488 // Fill the remaining fields with one pointer filler map.
489 485
490 __ bind(&no_inobject_slack_tracking); 486 __ bind(&no_inobject_slack_tracking);
491 } 487 }
492 488
493 __ InitializeFieldsWithFiller(t5, t3, t7); 489 __ InitializeFieldsWithFiller(t5, t3, t7);
494 490
495 // Add the object tag to make the JSObject real, so that we can continue 491 // 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. 492 // and jump into the continuation code at any time from now on.
497 __ Addu(t4, t4, Operand(kHeapObjectTag)); 493 __ Addu(t4, t4, Operand(kHeapObjectTag));
498 494
499 // Continue with JSObject being successfully allocated. 495 // Continue with JSObject being successfully allocated.
496 // a1: constructor function
497 // a3: new target
500 // t4: JSObject 498 // t4: JSObject
501 __ jmp(&allocated); 499 __ jmp(&allocated);
502
503 // Reload the new target and fall-through.
504 __ bind(&rt_call_reload_new_target);
505 __ lw(a3, MemOperand(sp, 0 * kPointerSize));
506 } 500 }
507 501
508 // Allocate the new receiver object using the runtime call. 502 // Allocate the new receiver object using the runtime call.
509 // a1: constructor function 503 // a1: constructor function
510 // a3: new target 504 // a3: new target
511 __ bind(&rt_call); 505 __ bind(&rt_call);
512 506
513 __ Push(a1, a3); // constructor function, new target 507 // Push the constructor and new_target twice, second pair as arguments
508 // to the runtime call.
509 __ Push(a1, a3, a1, a3); // constructor function, new target
514 __ CallRuntime(Runtime::kNewObject, 2); 510 __ CallRuntime(Runtime::kNewObject, 2);
515 __ mov(t4, v0); 511 __ mov(t4, v0);
512 __ Pop(a1, a3);
516 513
517 // Receiver for constructor call allocated. 514 // Receiver for constructor call allocated.
515 // a1: constructor function
516 // a3: new target
518 // t4: JSObject 517 // t4: JSObject
519 __ bind(&allocated); 518 __ bind(&allocated);
520 519
521 // Restore the parameters.
522 __ Pop(a3); // new.target
523 __ Pop(a1);
524
525 // Retrieve smi-tagged arguments count from the stack. 520 // Retrieve smi-tagged arguments count from the stack.
526 __ lw(a0, MemOperand(sp)); 521 __ lw(a0, MemOperand(sp));
527 } 522 }
528 523
529 __ SmiUntag(a0); 524 __ SmiUntag(a0);
530 525
531 // Push new.target onto the construct frame. This is stored just below the 526 // Push new.target onto the construct frame. This is stored just below the
532 // receiver on the stack. 527 // receiver on the stack.
533 if (create_implicit_receiver) { 528 if (create_implicit_receiver) {
534 // Push the allocated receiver to the stack. We need two copies 529 // Push the allocated receiver to the stack. We need two copies
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 } 1867 }
1873 } 1868 }
1874 1869
1875 1870
1876 #undef __ 1871 #undef __
1877 1872
1878 } // namespace internal 1873 } // namespace internal
1879 } // namespace v8 1874 } // namespace v8
1880 1875
1881 #endif // V8_TARGET_ARCH_MIPS 1876 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698