| 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 #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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |