| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 | 253 |
| 254 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 254 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); |
| 255 GenerateTailCallToReturnedCode(masm); | 255 GenerateTailCallToReturnedCode(masm); |
| 256 | 256 |
| 257 __ bind(&ok); | 257 __ bind(&ok); |
| 258 GenerateTailCallToSharedCode(masm); | 258 GenerateTailCallToSharedCode(masm); |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 262 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 263 bool is_api_function, | 263 bool is_api_function) { |
| 264 bool create_memento) { | |
| 265 // ----------- S t a t e ------------- | 264 // ----------- S t a t e ------------- |
| 266 // -- r3 : number of arguments | 265 // -- r3 : number of arguments |
| 267 // -- r4 : constructor function | 266 // -- r4 : constructor function |
| 268 // -- r5 : allocation site or undefined | 267 // -- r5 : allocation site or undefined |
| 269 // -- r6 : original constructor | 268 // -- r6 : original constructor |
| 270 // -- lr : return address | 269 // -- lr : return address |
| 271 // -- sp[...]: constructor arguments | 270 // -- sp[...]: constructor arguments |
| 272 // ----------------------------------- | 271 // ----------------------------------- |
| 273 | 272 |
| 274 // Should never create mementos for api functions. | |
| 275 DCHECK(!is_api_function || !create_memento); | |
| 276 | |
| 277 Isolate* isolate = masm->isolate(); | 273 Isolate* isolate = masm->isolate(); |
| 278 | 274 |
| 279 // Enter a construct frame. | 275 // Enter a construct frame. |
| 280 { | 276 { |
| 281 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); | 277 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); |
| 282 | 278 |
| 283 // Preserve the incoming parameters on the stack. | 279 // Preserve the incoming parameters on the stack. |
| 284 __ AssertUndefinedOrAllocationSite(r5, r7); | 280 __ AssertUndefinedOrAllocationSite(r5, r7); |
| 285 __ SmiTag(r3); | 281 __ SmiTag(r3); |
| 286 __ Push(r5, r3, r4, r6); | 282 __ Push(r5, r3, r4, r6); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 __ Pop(r4, r5); | 334 __ Pop(r4, r5); |
| 339 | 335 |
| 340 __ bind(&allocate); | 336 __ bind(&allocate); |
| 341 } | 337 } |
| 342 | 338 |
| 343 // Now allocate the JSObject on the heap. | 339 // Now allocate the JSObject on the heap. |
| 344 // r4: constructor function | 340 // r4: constructor function |
| 345 // r5: initial map | 341 // r5: initial map |
| 346 Label rt_call_reload_new_target; | 342 Label rt_call_reload_new_target; |
| 347 __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset)); | 343 __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset)); |
| 348 if (create_memento) { | |
| 349 __ addi(r6, r6, Operand(AllocationMemento::kSize / kPointerSize)); | |
| 350 } | |
| 351 | 344 |
| 352 __ Allocate(r6, r7, r8, r9, &rt_call_reload_new_target, SIZE_IN_WORDS); | 345 __ Allocate(r6, r7, r8, r9, &rt_call_reload_new_target, SIZE_IN_WORDS); |
| 353 | 346 |
| 354 // Allocated the JSObject, now initialize the fields. Map is set to | 347 // Allocated the JSObject, now initialize the fields. Map is set to |
| 355 // initial map and properties and elements are set to empty fixed array. | 348 // initial map and properties and elements are set to empty fixed array. |
| 356 // r4: constructor function | 349 // r4: constructor function |
| 357 // r5: initial map | 350 // r5: initial map |
| 358 // r6: object size (including memento if create_memento) | 351 // r6: object size |
| 359 // r7: JSObject (not tagged) | 352 // r7: JSObject (not tagged) |
| 360 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); | 353 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); |
| 361 __ mr(r8, r7); | 354 __ mr(r8, r7); |
| 362 __ StoreP(r5, MemOperand(r8, JSObject::kMapOffset)); | 355 __ StoreP(r5, MemOperand(r8, JSObject::kMapOffset)); |
| 363 __ StoreP(r9, MemOperand(r8, JSObject::kPropertiesOffset)); | 356 __ StoreP(r9, MemOperand(r8, JSObject::kPropertiesOffset)); |
| 364 __ StoreP(r9, MemOperand(r8, JSObject::kElementsOffset)); | 357 __ StoreP(r9, MemOperand(r8, JSObject::kElementsOffset)); |
| 365 __ addi(r8, r8, Operand(JSObject::kElementsOffset + kPointerSize)); | 358 __ addi(r8, r8, Operand(JSObject::kElementsOffset + kPointerSize)); |
| 366 | 359 |
| 367 __ ShiftLeftImm(r9, r6, Operand(kPointerSizeLog2)); | 360 __ ShiftLeftImm(r9, r6, Operand(kPointerSizeLog2)); |
| 368 __ add(r9, r7, r9); // End of object. | 361 __ add(r9, r7, r9); // End of object. |
| 369 | 362 |
| 370 // Fill all the in-object properties with the appropriate filler. | 363 // Fill all the in-object properties with the appropriate filler. |
| 371 // r4: constructor function | 364 // r4: constructor function |
| 372 // r5: initial map | 365 // r5: initial map |
| 373 // r6: object size (in words, including memento if create_memento) | 366 // r6: object size |
| 374 // r7: JSObject (not tagged) | 367 // r7: JSObject (not tagged) |
| 375 // r8: First in-object property of JSObject (not tagged) | 368 // r8: First in-object property of JSObject (not tagged) |
| 376 // r9: End of object | 369 // r9: End of object |
| 377 DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize); | 370 DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize); |
| 378 __ LoadRoot(r10, Heap::kUndefinedValueRootIndex); | 371 __ LoadRoot(r10, Heap::kUndefinedValueRootIndex); |
| 379 | 372 |
| 380 if (!is_api_function) { | 373 if (!is_api_function) { |
| 381 Label no_inobject_slack_tracking; | 374 Label no_inobject_slack_tracking; |
| 382 | 375 |
| 383 // Check if slack tracking is enabled. | 376 // Check if slack tracking is enabled. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 405 __ InitializeNFieldsWithFiller(r8, r3, r10); | 398 __ InitializeNFieldsWithFiller(r8, r3, r10); |
| 406 __ bind(&done); | 399 __ bind(&done); |
| 407 } | 400 } |
| 408 // To allow for truncation. | 401 // To allow for truncation. |
| 409 __ LoadRoot(r10, Heap::kOnePointerFillerMapRootIndex); | 402 __ LoadRoot(r10, Heap::kOnePointerFillerMapRootIndex); |
| 410 // Fill the remaining fields with one pointer filler map. | 403 // Fill the remaining fields with one pointer filler map. |
| 411 | 404 |
| 412 __ bind(&no_inobject_slack_tracking); | 405 __ bind(&no_inobject_slack_tracking); |
| 413 } | 406 } |
| 414 | 407 |
| 415 if (create_memento) { | 408 __ InitializeFieldsWithFiller(r8, r9, r10); |
| 416 __ subi(r3, r9, Operand(AllocationMemento::kSize)); | |
| 417 __ InitializeFieldsWithFiller(r8, r3, r10); | |
| 418 | |
| 419 // Fill in memento fields. | |
| 420 // r8: points to the allocated but uninitialized memento. | |
| 421 __ LoadRoot(r10, Heap::kAllocationMementoMapRootIndex); | |
| 422 __ StoreP(r10, MemOperand(r8, AllocationMemento::kMapOffset)); | |
| 423 // Load the AllocationSite | |
| 424 __ LoadP(r10, MemOperand(sp, 3 * kPointerSize)); | |
| 425 __ AssertUndefinedOrAllocationSite(r10, r3); | |
| 426 __ StoreP(r10, | |
| 427 MemOperand(r8, AllocationMemento::kAllocationSiteOffset)); | |
| 428 __ addi(r8, r8, Operand(AllocationMemento::kAllocationSiteOffset + | |
| 429 kPointerSize)); | |
| 430 } else { | |
| 431 __ InitializeFieldsWithFiller(r8, r9, r10); | |
| 432 } | |
| 433 | 409 |
| 434 // Add the object tag to make the JSObject real, so that we can continue | 410 // Add the object tag to make the JSObject real, so that we can continue |
| 435 // and jump into the continuation code at any time from now on. | 411 // and jump into the continuation code at any time from now on. |
| 436 __ addi(r7, r7, Operand(kHeapObjectTag)); | 412 __ addi(r7, r7, Operand(kHeapObjectTag)); |
| 437 | 413 |
| 438 // Continue with JSObject being successfully allocated | 414 // Continue with JSObject being successfully allocated |
| 439 // r7: JSObject | 415 // r7: JSObject |
| 440 __ b(&allocated); | 416 __ b(&allocated); |
| 441 | 417 |
| 442 // Reload the original constructor and fall-through. | 418 // Reload the original constructor and fall-through. |
| 443 __ bind(&rt_call_reload_new_target); | 419 __ bind(&rt_call_reload_new_target); |
| 444 __ LoadP(r6, MemOperand(sp, 0 * kPointerSize)); | 420 __ LoadP(r6, MemOperand(sp, 0 * kPointerSize)); |
| 445 } | 421 } |
| 446 | 422 |
| 447 // Allocate the new receiver object using the runtime call. | 423 // Allocate the new receiver object using the runtime call. |
| 448 // r4: constructor function | 424 // r4: constructor function |
| 449 // r6: original constructor | 425 // r6: original constructor |
| 450 __ bind(&rt_call); | 426 __ bind(&rt_call); |
| 451 if (create_memento) { | 427 __ Push(r4, r6); |
| 452 // Get the cell or allocation site. | 428 __ CallRuntime(Runtime::kNewObject, 2); |
| 453 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize)); | |
| 454 __ Push(r5, r4, r6); | |
| 455 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); | |
| 456 } else { | |
| 457 __ Push(r4, r6); | |
| 458 __ CallRuntime(Runtime::kNewObject, 2); | |
| 459 } | |
| 460 __ mr(r7, r3); | 429 __ mr(r7, r3); |
| 461 | 430 |
| 462 // Runtime_NewObjectWithAllocationSite increments allocation count. | |
| 463 // Skip the increment. | |
| 464 Label count_incremented; | |
| 465 if (create_memento) { | |
| 466 __ b(&count_incremented); | |
| 467 } | |
| 468 | |
| 469 // Receiver for constructor call allocated. | 431 // Receiver for constructor call allocated. |
| 470 // r7: JSObject | 432 // r7: JSObject |
| 471 __ bind(&allocated); | 433 __ bind(&allocated); |
| 472 | 434 |
| 473 if (create_memento) { | |
| 474 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize)); | |
| 475 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); | |
| 476 __ cmp(r5, r8); | |
| 477 __ beq(&count_incremented); | |
| 478 // r5 is an AllocationSite. We are creating a memento from it, so we | |
| 479 // need to increment the memento create count. | |
| 480 __ LoadP( | |
| 481 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset)); | |
| 482 __ AddSmiLiteral(r6, r6, Smi::FromInt(1), r0); | |
| 483 __ StoreP( | |
| 484 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset), | |
| 485 r0); | |
| 486 __ bind(&count_incremented); | |
| 487 } | |
| 488 | |
| 489 // Restore the parameters. | 435 // Restore the parameters. |
| 490 __ Pop(r4, ip); | 436 __ Pop(r4, ip); |
| 491 | 437 |
| 492 // Retrieve smi-tagged arguments count from the stack. | 438 // Retrieve smi-tagged arguments count from the stack. |
| 493 __ LoadP(r6, MemOperand(sp)); | 439 __ LoadP(r6, MemOperand(sp)); |
| 494 | 440 |
| 495 // Push new.target onto the construct frame. This is stored just below the | 441 // Push new.target onto the construct frame. This is stored just below the |
| 496 // receiver on the stack. | 442 // receiver on the stack. |
| 497 __ Push(ip, r7, r7); | 443 __ Push(ip, r7, r7); |
| 498 | 444 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 | 526 |
| 581 __ SmiToPtrArrayOffset(r4, r4); | 527 __ SmiToPtrArrayOffset(r4, r4); |
| 582 __ add(sp, sp, r4); | 528 __ add(sp, sp, r4); |
| 583 __ addi(sp, sp, Operand(kPointerSize)); | 529 __ addi(sp, sp, Operand(kPointerSize)); |
| 584 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5); | 530 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5); |
| 585 __ blr(); | 531 __ blr(); |
| 586 } | 532 } |
| 587 | 533 |
| 588 | 534 |
| 589 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 535 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 590 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); | 536 Generate_JSConstructStubHelper(masm, false); |
| 591 } | 537 } |
| 592 | 538 |
| 593 | 539 |
| 594 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 540 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 595 Generate_JSConstructStubHelper(masm, true, false); | 541 Generate_JSConstructStubHelper(masm, true); |
| 596 } | 542 } |
| 597 | 543 |
| 598 | 544 |
| 599 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 545 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
| 600 // ----------- S t a t e ------------- | 546 // ----------- S t a t e ------------- |
| 601 // -- r3 : number of arguments | 547 // -- r3 : number of arguments |
| 602 // -- r4 : constructor function | 548 // -- r4 : constructor function |
| 603 // -- r5 : allocation site or undefined | 549 // -- r5 : allocation site or undefined |
| 604 // -- r6 : original constructor | 550 // -- r6 : original constructor |
| 605 // -- lr : return address | 551 // -- lr : return address |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1810 __ bkpt(0); | 1756 __ bkpt(0); |
| 1811 } | 1757 } |
| 1812 } | 1758 } |
| 1813 | 1759 |
| 1814 | 1760 |
| 1815 #undef __ | 1761 #undef __ |
| 1816 } // namespace internal | 1762 } // namespace internal |
| 1817 } // namespace v8 | 1763 } // namespace v8 |
| 1818 | 1764 |
| 1819 #endif // V8_TARGET_ARCH_PPC | 1765 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |