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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 // frames.h for its layout. | 992 // frames.h for its layout. |
993 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { | 993 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
994 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 994 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
995 | 995 |
996 // Open a frame scope to indicate that there is a frame on the stack. The | 996 // Open a frame scope to indicate that there is a frame on the stack. The |
997 // MANUAL indicates that the scope shouldn't actually generate code to set up | 997 // MANUAL indicates that the scope shouldn't actually generate code to set up |
998 // the frame (that is done below). | 998 // the frame (that is done below). |
999 FrameScope frame_scope(masm, StackFrame::MANUAL); | 999 FrameScope frame_scope(masm, StackFrame::MANUAL); |
1000 __ PushStandardFrame(r4); | 1000 __ PushStandardFrame(r4); |
1001 | 1001 |
1002 // Get the bytecode array from the function object and load the pointer to the | 1002 // Get the bytecode array from the function object (or from the DebugInfo if |
1003 // first entry into kInterpreterBytecodeRegister. | 1003 // it is present) and load it into kInterpreterBytecodeArrayRegister. |
1004 __ LoadP(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 1004 __ LoadP(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
1005 Label array_done; | 1005 Label array_done; |
1006 Register debug_info = r5; | 1006 Register debug_info = r5; |
1007 DCHECK(!debug_info.is(r3)); | 1007 DCHECK(!debug_info.is(r3)); |
1008 __ LoadP(debug_info, | 1008 __ LoadP(debug_info, |
1009 FieldMemOperand(r3, SharedFunctionInfo::kDebugInfoOffset)); | 1009 FieldMemOperand(r3, SharedFunctionInfo::kDebugInfoOffset)); |
1010 // Load original bytecode array or the debug copy. | 1010 // Load original bytecode array or the debug copy. |
1011 __ LoadP(kInterpreterBytecodeArrayRegister, | 1011 __ LoadP(kInterpreterBytecodeArrayRegister, |
1012 FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset)); | 1012 FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset)); |
1013 __ CmpSmiLiteral(debug_info, DebugInfo::uninitialized(), r0); | 1013 __ CmpSmiLiteral(debug_info, DebugInfo::uninitialized(), r0); |
1014 __ beq(&array_done); | 1014 __ beq(&array_done); |
1015 __ LoadP(kInterpreterBytecodeArrayRegister, | 1015 __ LoadP(kInterpreterBytecodeArrayRegister, |
1016 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex)); | 1016 FieldMemOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
1017 __ bind(&array_done); | 1017 __ bind(&array_done); |
1018 | 1018 |
| 1019 // Check function data field is actually a BytecodeArray object. |
| 1020 Label bytecode_array_not_present; |
| 1021 __ CompareRoot(kInterpreterBytecodeArrayRegister, |
| 1022 Heap::kUndefinedValueRootIndex); |
| 1023 __ beq(&bytecode_array_not_present); |
| 1024 |
1019 if (FLAG_debug_code) { | 1025 if (FLAG_debug_code) { |
1020 // Check function data field is actually a BytecodeArray object. | |
1021 __ TestIfSmi(kInterpreterBytecodeArrayRegister, r0); | 1026 __ TestIfSmi(kInterpreterBytecodeArrayRegister, r0); |
1022 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 1027 __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
1023 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r3, no_reg, | 1028 __ CompareObjectType(kInterpreterBytecodeArrayRegister, r3, no_reg, |
1024 BYTECODE_ARRAY_TYPE); | 1029 BYTECODE_ARRAY_TYPE); |
1025 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 1030 __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
1026 } | 1031 } |
1027 | 1032 |
1028 // Push new.target, bytecode array and zero for bytecode array offset. | 1033 // Push new.target, bytecode array and zero for bytecode array offset. |
1029 __ li(r3, Operand::Zero()); | 1034 __ li(r3, Operand::Zero()); |
1030 __ Push(r6, kInterpreterBytecodeArrayRegister, r3); | 1035 __ Push(r6, kInterpreterBytecodeArrayRegister, r3); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 | 1074 |
1070 // Dispatch to the first bytecode handler for the function. | 1075 // Dispatch to the first bytecode handler for the function. |
1071 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, | 1076 __ lbzx(r4, MemOperand(kInterpreterBytecodeArrayRegister, |
1072 kInterpreterBytecodeOffsetRegister)); | 1077 kInterpreterBytecodeOffsetRegister)); |
1073 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); | 1078 __ ShiftLeftImm(ip, r4, Operand(kPointerSizeLog2)); |
1074 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); | 1079 __ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip)); |
1075 __ Call(ip); | 1080 __ Call(ip); |
1076 | 1081 |
1077 // Even though the first bytecode handler was called, we will never return. | 1082 // Even though the first bytecode handler was called, we will never return. |
1078 __ Abort(kUnexpectedReturnFromBytecodeHandler); | 1083 __ Abort(kUnexpectedReturnFromBytecodeHandler); |
| 1084 |
| 1085 // If the bytecode array is no longer present, then the underlying function |
| 1086 // has been switched to a different kind of code and we heal the closure by |
| 1087 // switching the code entry field over to the new code object as well. |
| 1088 __ bind(&bytecode_array_not_present); |
| 1089 __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
| 1090 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 1091 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kCodeOffset)); |
| 1092 __ addi(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1093 __ StoreP(r7, FieldMemOperand(r4, JSFunction::kCodeEntryOffset), r0); |
| 1094 __ RecordWriteCodeEntryField(r4, r7, r8); |
| 1095 __ JumpToJSEntry(r7); |
1079 } | 1096 } |
1080 | 1097 |
1081 | 1098 |
1082 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { | 1099 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
1083 // The return value is in accumulator, which is already in r3. | 1100 // The return value is in accumulator, which is already in r3. |
1084 | 1101 |
1085 // Leave the frame (also dropping the register file). | 1102 // Leave the frame (also dropping the register file). |
1086 __ LeaveFrame(StackFrame::JAVA_SCRIPT); | 1103 __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
1087 | 1104 |
1088 // Drop receiver + arguments and return. | 1105 // Drop receiver + arguments and return. |
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2852 __ bkpt(0); | 2869 __ bkpt(0); |
2853 } | 2870 } |
2854 } | 2871 } |
2855 | 2872 |
2856 | 2873 |
2857 #undef __ | 2874 #undef __ |
2858 } // namespace internal | 2875 } // namespace internal |
2859 } // namespace v8 | 2876 } // namespace v8 |
2860 | 2877 |
2861 #endif // V8_TARGET_ARCH_PPC | 2878 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |