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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 __ lbz(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset)); | 1423 __ lbz(scratch, FieldMemOperand(function_map, Map::kBitFieldOffset)); |
1424 __ TestBit(scratch, Map::kHasNonInstancePrototype, r0); | 1424 __ TestBit(scratch, Map::kHasNonInstancePrototype, r0); |
1425 __ bne(&slow_case, cr0); | 1425 __ bne(&slow_case, cr0); |
1426 | 1426 |
1427 // Ensure that {function} is not bound. | 1427 // Ensure that {function} is not bound. |
1428 Register const shared_info = scratch; | 1428 Register const shared_info = scratch; |
1429 __ LoadP(shared_info, | 1429 __ LoadP(shared_info, |
1430 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 1430 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
1431 __ lwz(scratch, FieldMemOperand(shared_info, | 1431 __ lwz(scratch, FieldMemOperand(shared_info, |
1432 SharedFunctionInfo::kCompilerHintsOffset)); | 1432 SharedFunctionInfo::kCompilerHintsOffset)); |
1433 __ TestBit(scratch, | 1433 __ TestBit(scratch, SharedFunctionInfo::kBoundBit, r0); |
1434 #if V8_TARGET_ARCH_PPC64 | |
1435 SharedFunctionInfo::kBoundFunction, | |
1436 #else | |
1437 SharedFunctionInfo::kBoundFunction + kSmiTagSize, | |
1438 #endif | |
1439 r0); | |
1440 __ bne(&slow_case, cr0); | 1434 __ bne(&slow_case, cr0); |
1441 | 1435 |
1442 // Get the "prototype" (or initial map) of the {function}. | 1436 // Get the "prototype" (or initial map) of the {function}. |
1443 __ LoadP(function_prototype, | 1437 __ LoadP(function_prototype, |
1444 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 1438 FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
1445 __ AssertNotSmi(function_prototype); | 1439 __ AssertNotSmi(function_prototype); |
1446 | 1440 |
1447 // Resolve the prototype if the {function} has an initial map. Afterwards the | 1441 // Resolve the prototype if the {function} has an initial map. Afterwards the |
1448 // {function_prototype} will be either the JSReceiver prototype object or the | 1442 // {function_prototype} will be either the JSReceiver prototype object or the |
1449 // hole value, which means that no instances of the {function} were created so | 1443 // hole value, which means that no instances of the {function} were created so |
(...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2529 | 2523 |
2530 __ bind(¬_array_function); | 2524 __ bind(¬_array_function); |
2531 | 2525 |
2532 CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2526 CreateWeakCellStub weak_cell_stub(masm->isolate()); |
2533 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2527 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); |
2534 __ bind(&done); | 2528 __ bind(&done); |
2535 } | 2529 } |
2536 | 2530 |
2537 | 2531 |
2538 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2532 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2533 // ----------- S t a t e ------------- |
| 2534 // -- r4 : the function to call |
| 2535 // -- r6 : the function's shared function info |
| 2536 // ----------------------------------- |
2539 // Do not transform the receiver for strict mode functions and natives. | 2537 // Do not transform the receiver for strict mode functions and natives. |
2540 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | |
2541 __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); | 2538 __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); |
2542 __ TestBit(r7, | 2539 __ andi(r0, r7, Operand((1 << SharedFunctionInfo::kStrictModeBit) | |
2543 #if V8_TARGET_ARCH_PPC64 | 2540 (1 << SharedFunctionInfo::kNativeBit))); |
2544 SharedFunctionInfo::kStrictModeFunction, | |
2545 #else | |
2546 SharedFunctionInfo::kStrictModeFunction + kSmiTagSize, | |
2547 #endif | |
2548 r0); | |
2549 __ bne(cont, cr0); | |
2550 | |
2551 // Do not transform the receiver for native. | |
2552 __ TestBit(r7, | |
2553 #if V8_TARGET_ARCH_PPC64 | |
2554 SharedFunctionInfo::kNative, | |
2555 #else | |
2556 SharedFunctionInfo::kNative + kSmiTagSize, | |
2557 #endif | |
2558 r0); | |
2559 __ bne(cont, cr0); | 2541 __ bne(cont, cr0); |
2560 } | 2542 } |
2561 | 2543 |
2562 | 2544 |
2563 static void EmitSlowCase(MacroAssembler* masm, int argc) { | 2545 static void EmitSlowCase(MacroAssembler* masm, int argc) { |
2564 __ mov(r3, Operand(argc)); | 2546 __ mov(r3, Operand(argc)); |
2565 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2547 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2566 } | 2548 } |
2567 | 2549 |
2568 | 2550 |
2569 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2551 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
2570 // Wrap the receiver and patch it back onto the stack. | 2552 // Wrap the receiver and patch it back onto the stack. |
2571 { | 2553 { |
2572 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); | 2554 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
2573 __ push(r4); | 2555 __ push(r4); |
2574 __ mr(r3, r6); | 2556 __ mr(r3, r6); |
2575 ToObjectStub stub(masm->isolate()); | 2557 ToObjectStub stub(masm->isolate()); |
2576 __ CallStub(&stub); | 2558 __ CallStub(&stub); |
2577 __ pop(r4); | 2559 __ pop(r4); |
2578 } | 2560 } |
2579 __ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0); | 2561 __ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0); |
2580 __ b(cont); | 2562 __ b(cont); |
2581 } | 2563 } |
2582 | 2564 |
2583 | 2565 |
| 2566 static void EmitClassConstructorCallCheck(MacroAssembler* masm) { |
| 2567 // ----------- S t a t e ------------- |
| 2568 // -- r4 : the function to call |
| 2569 // -- r6 : the function's shared function info |
| 2570 // ----------------------------------- |
| 2571 // ClassConstructor Check: ES6 section 9.2.1 [[Call]] |
| 2572 Label non_class_constructor; |
| 2573 // Check whether the current function is a classConstructor. |
| 2574 __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); |
| 2575 __ TestBitMask(r7, SharedFunctionInfo::kClassConstructorBits, r0); |
| 2576 __ beq(&non_class_constructor, cr0); |
| 2577 // If we call a classConstructor Function throw a TypeError |
| 2578 // indirectly via the CallFunction builtin. |
| 2579 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
| 2580 __ bind(&non_class_constructor); |
| 2581 } |
| 2582 |
| 2583 |
2584 static void CallFunctionNoFeedback(MacroAssembler* masm, int argc, | 2584 static void CallFunctionNoFeedback(MacroAssembler* masm, int argc, |
2585 bool needs_checks, bool call_as_method) { | 2585 bool needs_checks, bool call_as_method) { |
2586 // r4 : the function to call | 2586 // r4 : the function to call |
2587 Label slow, wrap, cont; | 2587 Label slow, wrap, cont; |
2588 | 2588 |
2589 if (needs_checks) { | 2589 if (needs_checks) { |
2590 // Check that the function is really a JavaScript function. | 2590 // Check that the function is really a JavaScript function. |
2591 // r4: pushed function (to be verified) | 2591 // r4: pushed function (to be verified) |
2592 __ JumpIfSmi(r4, &slow); | 2592 __ JumpIfSmi(r4, &slow); |
2593 | 2593 |
2594 // Goto slow case if we do not have a function. | 2594 // Goto slow case if we do not have a function. |
2595 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); | 2595 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); |
2596 __ bne(&slow); | 2596 __ bne(&slow); |
2597 } | 2597 } |
2598 | 2598 |
| 2599 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 2600 EmitClassConstructorCallCheck(masm); |
| 2601 |
2599 // Fast-case: Invoke the function now. | 2602 // Fast-case: Invoke the function now. |
2600 // r4: pushed function | 2603 // r4: pushed function |
2601 ParameterCount actual(argc); | 2604 ParameterCount actual(argc); |
2602 | 2605 |
2603 if (call_as_method) { | 2606 if (call_as_method) { |
2604 if (needs_checks) { | 2607 if (needs_checks) { |
2605 EmitContinueIfStrictOrNative(masm, &cont); | 2608 EmitContinueIfStrictOrNative(masm, &cont); |
2606 } | 2609 } |
2607 | 2610 |
2608 // Compute the receiver in sloppy mode. | 2611 // Compute the receiver in sloppy mode. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2762 // convincing us that we have a monomorphic JSFunction. | 2765 // convincing us that we have a monomorphic JSFunction. |
2763 __ JumpIfSmi(r4, &extra_checks_or_miss); | 2766 __ JumpIfSmi(r4, &extra_checks_or_miss); |
2764 | 2767 |
2765 // Increment the call count for monomorphic function calls. | 2768 // Increment the call count for monomorphic function calls. |
2766 const int count_offset = FixedArray::kHeaderSize + kPointerSize; | 2769 const int count_offset = FixedArray::kHeaderSize + kPointerSize; |
2767 __ LoadP(r6, FieldMemOperand(r9, count_offset)); | 2770 __ LoadP(r6, FieldMemOperand(r9, count_offset)); |
2768 __ AddSmiLiteral(r6, r6, Smi::FromInt(CallICNexus::kCallCountIncrement), r0); | 2771 __ AddSmiLiteral(r6, r6, Smi::FromInt(CallICNexus::kCallCountIncrement), r0); |
2769 __ StoreP(r6, FieldMemOperand(r9, count_offset), r0); | 2772 __ StoreP(r6, FieldMemOperand(r9, count_offset), r0); |
2770 | 2773 |
2771 __ bind(&have_js_function); | 2774 __ bind(&have_js_function); |
| 2775 |
| 2776 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 2777 EmitClassConstructorCallCheck(masm); |
| 2778 |
2772 if (CallAsMethod()) { | 2779 if (CallAsMethod()) { |
2773 EmitContinueIfStrictOrNative(masm, &cont); | 2780 EmitContinueIfStrictOrNative(masm, &cont); |
2774 // Compute the receiver in sloppy mode. | 2781 // Compute the receiver in sloppy mode. |
2775 __ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0); | 2782 __ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0); |
2776 | 2783 |
2777 __ JumpIfSmi(r6, &wrap); | 2784 __ JumpIfSmi(r6, &wrap); |
2778 __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE); | 2785 __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE); |
2779 __ blt(&wrap); | 2786 __ blt(&wrap); |
2780 | 2787 |
2781 __ bind(&cont); | 2788 __ bind(&cont); |
(...skipping 3081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5863 kStackUnwindSpace, NULL, | 5870 kStackUnwindSpace, NULL, |
5864 MemOperand(fp, 6 * kPointerSize), NULL); | 5871 MemOperand(fp, 6 * kPointerSize), NULL); |
5865 } | 5872 } |
5866 | 5873 |
5867 | 5874 |
5868 #undef __ | 5875 #undef __ |
5869 } // namespace internal | 5876 } // namespace internal |
5870 } // namespace v8 | 5877 } // namespace v8 |
5871 | 5878 |
5872 #endif // V8_TARGET_ARCH_PPC | 5879 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |