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

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

Issue 1234953002: PPC: Cleanup Generate_JSConstructStubHelper a bit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 __ bge(&ok); 300 __ bge(&ok);
301 301
302 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 302 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
303 GenerateTailCallToReturnedCode(masm); 303 GenerateTailCallToReturnedCode(masm);
304 304
305 __ bind(&ok); 305 __ bind(&ok);
306 GenerateTailCallToSharedCode(masm); 306 GenerateTailCallToSharedCode(masm);
307 } 307 }
308 308
309 309
310 static void Generate_Runtime_NewObject(MacroAssembler* masm,
311 bool create_memento,
312 Register original_constructor,
313 Label* count_incremented,
314 Label* allocated) {
315 // ----------- S t a t e -------------
316 // -- r4: argument for Runtime_NewObject
317 // -----------------------------------
318 Register result = r7;
319
320 if (create_memento) {
321 // Get the cell or allocation site.
322 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize));
323 __ Push(r5, r4, original_constructor);
324 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
325 __ mr(result, r3);
326 // Runtime_NewObjectWithAllocationSite increments allocation count.
327 // Skip the increment.
328 __ b(count_incremented);
329 } else {
330 __ Push(r4, original_constructor);
331 __ CallRuntime(Runtime::kNewObject, 2);
332 __ mr(result, r3);
333 __ b(allocated);
334 }
335 }
336
337
338 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 310 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
339 bool is_api_function, 311 bool is_api_function,
340 bool create_memento) { 312 bool create_memento) {
341 // ----------- S t a t e ------------- 313 // ----------- S t a t e -------------
342 // -- r3 : number of arguments 314 // -- r3 : number of arguments
343 // -- r4 : constructor function 315 // -- r4 : constructor function
344 // -- r5 : allocation site or undefined 316 // -- r5 : allocation site or undefined
345 // -- r6 : original constructor 317 // -- r6 : original constructor
346 // -- lr : return address 318 // -- lr : return address
347 // -- sp[...]: constructor arguments 319 // -- sp[...]: constructor arguments
(...skipping 10 matching lines...) Expand all
358 330
359 if (create_memento) { 331 if (create_memento) {
360 __ AssertUndefinedOrAllocationSite(r5, r7); 332 __ AssertUndefinedOrAllocationSite(r5, r7);
361 __ push(r5); 333 __ push(r5);
362 } 334 }
363 335
364 // Preserve the incoming parameters on the stack. 336 // Preserve the incoming parameters on the stack.
365 __ SmiTag(r3); 337 __ SmiTag(r3);
366 __ Push(r3, r4, r6); 338 __ Push(r3, r4, r6);
367 339
368 Label rt_call, allocated, normal_new, count_incremented;
369 __ cmp(r4, r6);
370 __ beq(&normal_new);
371
372 // Original constructor and function are different.
373 Generate_Runtime_NewObject(masm, create_memento, r6, &count_incremented,
374 &allocated);
375 __ bind(&normal_new);
376
377 // Try to allocate the object without transitioning into C code. If any of 340 // Try to allocate the object without transitioning into C code. If any of
378 // the preconditions is not met, the code bails out to the runtime call. 341 // the preconditions is not met, the code bails out to the runtime call.
342 Label rt_call, allocated;
379 if (FLAG_inline_new) { 343 if (FLAG_inline_new) {
380 ExternalReference debug_step_in_fp = 344 ExternalReference debug_step_in_fp =
381 ExternalReference::debug_step_in_fp_address(isolate); 345 ExternalReference::debug_step_in_fp_address(isolate);
382 __ mov(r5, Operand(debug_step_in_fp)); 346 __ mov(r5, Operand(debug_step_in_fp));
383 __ LoadP(r5, MemOperand(r5)); 347 __ LoadP(r5, MemOperand(r5));
384 __ cmpi(r5, Operand::Zero()); 348 __ cmpi(r5, Operand::Zero());
385 __ bne(&rt_call); 349 __ bne(&rt_call);
386 350
351 // Fall back to runtime if the original constructor and function differ.
352 __ cmp(r4, r6);
353 __ bne(&rt_call);
354
387 // Load the initial map and verify that it is in fact a map. 355 // Load the initial map and verify that it is in fact a map.
388 // r4: constructor function 356 // r4: constructor function
389 __ LoadP(r5, 357 __ LoadP(r5,
390 FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset)); 358 FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
391 __ JumpIfSmi(r5, &rt_call); 359 __ JumpIfSmi(r5, &rt_call);
392 __ CompareObjectType(r5, r6, r7, MAP_TYPE); 360 __ CompareObjectType(r5, r8, r7, MAP_TYPE);
393 __ bne(&rt_call); 361 __ bne(&rt_call);
394 362
395 // Check that the constructor is not constructing a JSFunction (see 363 // Check that the constructor is not constructing a JSFunction (see
396 // comments in Runtime_NewObject in runtime.cc). In which case the 364 // comments in Runtime_NewObject in runtime.cc). In which case the
397 // initial map's instance type would be JS_FUNCTION_TYPE. 365 // initial map's instance type would be JS_FUNCTION_TYPE.
398 // r4: constructor function 366 // r4: constructor function
399 // r5: initial map 367 // r5: initial map
400 __ CompareInstanceType(r5, r6, JS_FUNCTION_TYPE); 368 __ CompareInstanceType(r5, r8, JS_FUNCTION_TYPE);
401 __ beq(&rt_call); 369 __ beq(&rt_call);
402 370
403 if (!is_api_function) { 371 if (!is_api_function) {
404 Label allocate; 372 Label allocate;
405 MemOperand bit_field3 = FieldMemOperand(r5, Map::kBitField3Offset); 373 MemOperand bit_field3 = FieldMemOperand(r5, Map::kBitField3Offset);
406 // Check if slack tracking is enabled. 374 // Check if slack tracking is enabled.
407 __ lwz(r7, bit_field3); 375 __ lwz(r7, bit_field3);
408 __ DecodeField<Map::Counter>(r11, r7); 376 __ DecodeField<Map::Counter>(r11, r7);
409 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd)); 377 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd));
410 __ blt(&allocate); 378 __ blt(&allocate);
411 // Decrease generous allocation count. 379 // Decrease generous allocation count.
412 __ Add(r7, r7, -(1 << Map::Counter::kShift), r0); 380 __ Add(r7, r7, -(1 << Map::Counter::kShift), r0);
413 __ stw(r7, bit_field3); 381 __ stw(r7, bit_field3);
414 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd)); 382 __ cmpi(r11, Operand(Map::kSlackTrackingCounterEnd));
415 __ bne(&allocate); 383 __ bne(&allocate);
416 384
417 __ push(r4); 385 __ push(r4);
418 386
419 __ Push(r5, r4); // r4 = constructor 387 __ Push(r5, r4); // r4 = constructor
420 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 388 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
421 389
422 __ Pop(r4, r5); 390 __ Pop(r4, r5);
423 391
424 __ bind(&allocate); 392 __ bind(&allocate);
425 } 393 }
426 394
427 // Now allocate the JSObject on the heap. 395 // Now allocate the JSObject on the heap.
428 // r4: constructor function 396 // r4: constructor function
429 // r5: initial map 397 // r5: initial map
398 Label rt_call_reload_new_target;
430 __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset)); 399 __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset));
431 if (create_memento) { 400 if (create_memento) {
432 __ addi(r6, r6, Operand(AllocationMemento::kSize / kPointerSize)); 401 __ addi(r6, r6, Operand(AllocationMemento::kSize / kPointerSize));
433 } 402 }
434 403
435 __ Allocate(r6, r7, r8, r9, &rt_call, SIZE_IN_WORDS); 404 __ Allocate(r6, r7, r8, r9, &rt_call_reload_new_target, SIZE_IN_WORDS);
436 405
437 // Allocated the JSObject, now initialize the fields. Map is set to 406 // Allocated the JSObject, now initialize the fields. Map is set to
438 // initial map and properties and elements are set to empty fixed array. 407 // initial map and properties and elements are set to empty fixed array.
439 // r4: constructor function 408 // r4: constructor function
440 // r5: initial map 409 // r5: initial map
441 // r6: object size (including memento if create_memento) 410 // r6: object size (including memento if create_memento)
442 // r7: JSObject (not tagged) 411 // r7: JSObject (not tagged)
443 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); 412 __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex);
444 __ mr(r8, r7); 413 __ mr(r8, r7);
445 __ StoreP(r5, MemOperand(r8, JSObject::kMapOffset)); 414 __ StoreP(r5, MemOperand(r8, JSObject::kMapOffset));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 __ InitializeFieldsWithFiller(r8, r9, r10); 479 __ InitializeFieldsWithFiller(r8, r9, r10);
511 } 480 }
512 481
513 // Add the object tag to make the JSObject real, so that we can continue 482 // Add the object tag to make the JSObject real, so that we can continue
514 // and jump into the continuation code at any time from now on. 483 // and jump into the continuation code at any time from now on.
515 __ addi(r7, r7, Operand(kHeapObjectTag)); 484 __ addi(r7, r7, Operand(kHeapObjectTag));
516 485
517 // Continue with JSObject being successfully allocated 486 // Continue with JSObject being successfully allocated
518 // r7: JSObject 487 // r7: JSObject
519 __ b(&allocated); 488 __ b(&allocated);
489
490 // Reload the original constructor and fall-through.
491 __ bind(&rt_call_reload_new_target);
492 __ LoadP(r6, MemOperand(sp, 0 * kPointerSize));
520 } 493 }
521 494
522 // Allocate the new receiver object using the runtime call. 495 // Allocate the new receiver object using the runtime call.
523 // r4: constructor function 496 // r4: constructor function
497 // r6: original constructor
524 __ bind(&rt_call); 498 __ bind(&rt_call);
525 Generate_Runtime_NewObject(masm, create_memento, r4, &count_incremented, 499 if (create_memento) {
526 &allocated); 500 // Get the cell or allocation site.
501 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize));
502 __ Push(r5, r4, r6);
503 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
504 } else {
505 __ Push(r4, r6);
506 __ CallRuntime(Runtime::kNewObject, 2);
507 }
508 __ mr(r7, r3);
509
510 // Runtime_NewObjectWithAllocationSite increments allocation count.
511 // Skip the increment.
512 Label count_incremented;
513 if (create_memento) {
514 __ b(&count_incremented);
515 }
527 516
528 // Receiver for constructor call allocated. 517 // Receiver for constructor call allocated.
529 // r7: JSObject 518 // r7: JSObject
530 __ bind(&allocated); 519 __ bind(&allocated);
531 520
532 if (create_memento) { 521 if (create_memento) {
533 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize)); 522 __ LoadP(r5, MemOperand(sp, 3 * kPointerSize));
534 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); 523 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
535 __ cmp(r5, r8); 524 __ cmp(r5, r8);
536 __ beq(&count_incremented); 525 __ beq(&count_incremented);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 // sp[2]: number of arguments (smi-tagged) 592 // sp[2]: number of arguments (smi-tagged)
604 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 593 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
605 594
606 // If the result is an object (in the ECMA sense), we should get rid 595 // If the result is an object (in the ECMA sense), we should get rid
607 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 596 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
608 // on page 74. 597 // on page 74.
609 Label use_receiver, exit; 598 Label use_receiver, exit;
610 599
611 // If the result is a smi, it is *not* an object in the ECMA sense. 600 // If the result is a smi, it is *not* an object in the ECMA sense.
612 // r3: result 601 // r3: result
613 // sp[0]: receiver (newly allocated object) 602 // sp[0]: receiver
614 // sp[1]: new.target 603 // sp[1]: new.target
615 // sp[2]: number of arguments (smi-tagged) 604 // sp[2]: number of arguments (smi-tagged)
616 __ JumpIfSmi(r3, &use_receiver); 605 __ JumpIfSmi(r3, &use_receiver);
617 606
618 // If the type of the result (stored in its map) is less than 607 // If the type of the result (stored in its map) is less than
619 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 608 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
620 __ CompareObjectType(r3, r4, r6, FIRST_SPEC_OBJECT_TYPE); 609 __ CompareObjectType(r3, r4, r6, FIRST_SPEC_OBJECT_TYPE);
621 __ bge(&exit); 610 __ bge(&exit);
622 611
623 // Throw away the result of the constructor invocation and use the 612 // Throw away the result of the constructor invocation and use the
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 __ bkpt(0); 1785 __ bkpt(0);
1797 } 1786 }
1798 } 1787 }
1799 1788
1800 1789
1801 #undef __ 1790 #undef __
1802 } // namespace internal 1791 } // namespace internal
1803 } // namespace v8 1792 } // namespace v8
1804 1793
1805 #endif // V8_TARGET_ARCH_PPC 1794 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698