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 |