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/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 isolate->set_fp_stubs_generated(true); | 988 isolate->set_fp_stubs_generated(true); |
989 } | 989 } |
990 | 990 |
991 | 991 |
992 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 992 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
993 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 993 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
994 stub.GetCode(); | 994 stub.GetCode(); |
995 } | 995 } |
996 | 996 |
997 | 997 |
| 998 static void ThrowPendingException(MacroAssembler* masm) { |
| 999 Isolate* isolate = masm->isolate(); |
| 1000 |
| 1001 ExternalReference pending_handler_context_address( |
| 1002 Isolate::kPendingHandlerContextAddress, isolate); |
| 1003 ExternalReference pending_handler_code_address( |
| 1004 Isolate::kPendingHandlerCodeAddress, isolate); |
| 1005 ExternalReference pending_handler_offset_address( |
| 1006 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 1007 ExternalReference pending_handler_fp_address( |
| 1008 Isolate::kPendingHandlerFPAddress, isolate); |
| 1009 ExternalReference pending_handler_sp_address( |
| 1010 Isolate::kPendingHandlerSPAddress, isolate); |
| 1011 |
| 1012 // Ask the runtime for help to determine the handler. This will set r3 to |
| 1013 // contain the current pending exception, don't clobber it. |
| 1014 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 1015 { |
| 1016 FrameScope scope(masm, StackFrame::MANUAL); |
| 1017 __ PrepareCallCFunction(3, 0, r3); |
| 1018 __ li(r3, Operand::Zero()); |
| 1019 __ li(r4, Operand::Zero()); |
| 1020 __ mov(r5, Operand(ExternalReference::isolate_address(isolate))); |
| 1021 __ CallCFunction(find_handler, 3); |
| 1022 } |
| 1023 |
| 1024 // Retrieve the handler context, SP and FP. |
| 1025 __ mov(cp, Operand(pending_handler_context_address)); |
| 1026 __ LoadP(cp, MemOperand(cp)); |
| 1027 __ mov(sp, Operand(pending_handler_sp_address)); |
| 1028 __ LoadP(sp, MemOperand(sp)); |
| 1029 __ mov(fp, Operand(pending_handler_fp_address)); |
| 1030 __ LoadP(fp, MemOperand(fp)); |
| 1031 |
| 1032 // If the handler is a JS frame, restore the context to the frame. |
| 1033 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1034 // or cp. |
| 1035 Label skip; |
| 1036 __ cmpi(cp, Operand::Zero()); |
| 1037 __ beq(&skip); |
| 1038 __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1039 __ bind(&skip); |
| 1040 |
| 1041 // Compute the handler entry address and jump to it. |
| 1042 __ mov(r4, Operand(pending_handler_code_address)); |
| 1043 __ LoadP(r4, MemOperand(r4)); |
| 1044 __ mov(r5, Operand(pending_handler_offset_address)); |
| 1045 __ LoadP(r5, MemOperand(r5)); |
| 1046 __ addi(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); // Code start |
| 1047 __ add(ip, r4, r5); |
| 1048 __ Jump(ip); |
| 1049 } |
| 1050 |
| 1051 |
998 void CEntryStub::Generate(MacroAssembler* masm) { | 1052 void CEntryStub::Generate(MacroAssembler* masm) { |
999 // Called from JavaScript; parameters are on stack as if calling JS function. | 1053 // Called from JavaScript; parameters are on stack as if calling JS function. |
1000 // r3: number of arguments including receiver | 1054 // r3: number of arguments including receiver |
1001 // r4: pointer to builtin function | 1055 // r4: pointer to builtin function |
1002 // fp: frame pointer (restored after C call) | 1056 // fp: frame pointer (restored after C call) |
1003 // sp: stack pointer (restored as callee's sp after C call) | 1057 // sp: stack pointer (restored as callee's sp after C call) |
1004 // cp: current context (C callee-saved) | 1058 // cp: current context (C callee-saved) |
1005 | 1059 |
1006 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1060 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
1007 | 1061 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 __ Move(ip, r15); | 1117 __ Move(ip, r15); |
1064 Register target = ip; | 1118 Register target = ip; |
1065 #else | 1119 #else |
1066 Register target = r15; | 1120 Register target = r15; |
1067 #endif | 1121 #endif |
1068 | 1122 |
1069 // To let the GC traverse the return address of the exit frames, we need to | 1123 // To let the GC traverse the return address of the exit frames, we need to |
1070 // know where the return address is. The CEntryStub is unmovable, so | 1124 // know where the return address is. The CEntryStub is unmovable, so |
1071 // we can store the address on the stack to be able to find it again and | 1125 // we can store the address on the stack to be able to find it again and |
1072 // we never have to restore it, because it will not change. | 1126 // we never have to restore it, because it will not change. |
1073 Label after_call; | 1127 // Compute the return address in lr to return to after the jump below. Pc is |
1074 __ mov_label_addr(r0, &after_call); | 1128 // already at '+ 8' from the current instruction but return is after three |
1075 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); | 1129 // instructions so add another 4 to pc to get the return address. |
1076 __ Call(target); | 1130 { |
1077 __ bind(&after_call); | 1131 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
| 1132 Label here; |
| 1133 __ b(&here, SetLK); |
| 1134 __ bind(&here); |
| 1135 __ mflr(r8); |
| 1136 |
| 1137 // Constant used below is dependent on size of Call() macro instructions |
| 1138 __ addi(r0, r8, Operand(20)); |
| 1139 |
| 1140 __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); |
| 1141 __ Call(target); |
| 1142 } |
1078 | 1143 |
1079 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS | 1144 #if !ABI_RETURNS_OBJECT_PAIRS_IN_REGS |
1080 // If return value is on the stack, pop it to registers. | 1145 // If return value is on the stack, pop it to registers. |
1081 if (result_size() > 1) { | 1146 if (result_size() > 1) { |
1082 __ LoadP(r4, MemOperand(r3, kPointerSize)); | 1147 __ LoadP(r4, MemOperand(r3, kPointerSize)); |
1083 __ LoadP(r3, MemOperand(r3)); | 1148 __ LoadP(r3, MemOperand(r3)); |
1084 } | 1149 } |
1085 #endif | 1150 #endif |
1086 | 1151 |
1087 // Runtime functions should not return 'the hole'. Allowing it to escape may | 1152 // Runtime functions should not return 'the hole'. Allowing it to escape may |
1088 // lead to crashes in the IC code later. | 1153 // lead to crashes in the IC code later. |
1089 if (FLAG_debug_code) { | 1154 if (FLAG_debug_code) { |
1090 Label okay; | 1155 Label okay; |
1091 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 1156 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
1092 __ bne(&okay); | 1157 __ bne(&okay); |
1093 __ stop("The hole escaped"); | 1158 __ stop("The hole escaped"); |
1094 __ bind(&okay); | 1159 __ bind(&okay); |
1095 } | 1160 } |
1096 | 1161 |
1097 // Check result for exception sentinel. | 1162 // Check result for exception sentinel. |
1098 Label exception_returned; | 1163 Label exception_returned; |
1099 __ CompareRoot(r3, Heap::kExceptionRootIndex); | 1164 __ CompareRoot(r3, Heap::kExceptionRootIndex); |
1100 __ beq(&exception_returned); | 1165 __ beq(&exception_returned); |
1101 | 1166 |
1102 ExternalReference pending_exception_address(Isolate::kPendingExceptionAddress, | |
1103 isolate()); | |
1104 | |
1105 // Check that there is no pending exception, otherwise we | 1167 // Check that there is no pending exception, otherwise we |
1106 // should have returned the exception sentinel. | 1168 // should have returned the exception sentinel. |
1107 if (FLAG_debug_code) { | 1169 if (FLAG_debug_code) { |
1108 Label okay; | 1170 Label okay; |
| 1171 ExternalReference pending_exception_address( |
| 1172 Isolate::kPendingExceptionAddress, isolate()); |
| 1173 |
1109 __ mov(r5, Operand(pending_exception_address)); | 1174 __ mov(r5, Operand(pending_exception_address)); |
1110 __ LoadP(r5, MemOperand(r5)); | 1175 __ LoadP(r5, MemOperand(r5)); |
1111 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 1176 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); |
1112 // Cannot use check here as it attempts to generate call into runtime. | 1177 // Cannot use check here as it attempts to generate call into runtime. |
1113 __ beq(&okay); | 1178 __ beq(&okay); |
1114 __ stop("Unexpected pending exception"); | 1179 __ stop("Unexpected pending exception"); |
1115 __ bind(&okay); | 1180 __ bind(&okay); |
1116 } | 1181 } |
1117 | 1182 |
1118 // Exit C frame and return. | 1183 // Exit C frame and return. |
1119 // r3:r4: result | 1184 // r3:r4: result |
1120 // sp: stack pointer | 1185 // sp: stack pointer |
1121 // fp: frame pointer | 1186 // fp: frame pointer |
1122 // r14: still holds argc (callee-saved). | 1187 // r14: still holds argc (callee-saved). |
1123 __ LeaveExitFrame(save_doubles(), r14, true); | 1188 __ LeaveExitFrame(save_doubles(), r14, true); |
1124 __ blr(); | 1189 __ blr(); |
1125 | 1190 |
1126 // Handling of exception. | 1191 // Handling of exception. |
1127 __ bind(&exception_returned); | 1192 __ bind(&exception_returned); |
1128 | 1193 |
1129 // Retrieve the pending exception. | 1194 ThrowPendingException(masm); |
1130 __ mov(r5, Operand(pending_exception_address)); | |
1131 __ LoadP(r3, MemOperand(r5)); | |
1132 | |
1133 // Clear the pending exception. | |
1134 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); | |
1135 __ StoreP(r6, MemOperand(r5)); | |
1136 | |
1137 // Special handling of termination exceptions which are uncatchable | |
1138 // by javascript code. | |
1139 Label throw_termination_exception; | |
1140 __ CompareRoot(r3, Heap::kTerminationExceptionRootIndex); | |
1141 __ beq(&throw_termination_exception); | |
1142 | |
1143 // Handle normal exception. | |
1144 __ Throw(r3); | |
1145 | |
1146 __ bind(&throw_termination_exception); | |
1147 __ ThrowUncatchable(r3); | |
1148 } | 1195 } |
1149 | 1196 |
1150 | 1197 |
1151 void JSEntryStub::Generate(MacroAssembler* masm) { | 1198 void JSEntryStub::Generate(MacroAssembler* masm) { |
1152 // r3: code entry | 1199 // r3: code entry |
1153 // r4: function | 1200 // r4: function |
1154 // r5: receiver | 1201 // r5: receiver |
1155 // r6: argc | 1202 // r6: argc |
1156 // [sp+0]: argv | 1203 // [sp+0]: argv |
1157 | 1204 |
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2357 // stack overflow (on the backtrack stack) was detected in RegExp code but | 2404 // stack overflow (on the backtrack stack) was detected in RegExp code but |
2358 // haven't created the exception yet. Handle that in the runtime system. | 2405 // haven't created the exception yet. Handle that in the runtime system. |
2359 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2406 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2360 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); | 2407 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); |
2361 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2408 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2362 isolate()))); | 2409 isolate()))); |
2363 __ LoadP(r3, MemOperand(r5, 0)); | 2410 __ LoadP(r3, MemOperand(r5, 0)); |
2364 __ cmp(r3, r4); | 2411 __ cmp(r3, r4); |
2365 __ beq(&runtime); | 2412 __ beq(&runtime); |
2366 | 2413 |
2367 __ StoreP(r4, MemOperand(r5, 0)); // Clear pending exception. | 2414 // For exception, throw the exception again. |
2368 | 2415 __ EnterExitFrame(false); |
2369 // Check if the exception is a termination. If so, throw as uncatchable. | 2416 ThrowPendingException(masm); |
2370 __ CompareRoot(r3, Heap::kTerminationExceptionRootIndex); | |
2371 | |
2372 Label termination_exception; | |
2373 __ beq(&termination_exception); | |
2374 | |
2375 __ Throw(r3); | |
2376 | |
2377 __ bind(&termination_exception); | |
2378 __ ThrowUncatchable(r3); | |
2379 | 2417 |
2380 __ bind(&failure); | 2418 __ bind(&failure); |
2381 // For failure and exception return null. | 2419 // For failure and exception return null. |
2382 __ mov(r3, Operand(isolate()->factory()->null_value())); | 2420 __ mov(r3, Operand(isolate()->factory()->null_value())); |
2383 __ addi(sp, sp, Operand(4 * kPointerSize)); | 2421 __ addi(sp, sp, Operand(4 * kPointerSize)); |
2384 __ Ret(); | 2422 __ Ret(); |
2385 | 2423 |
2386 // Process the result from the native regexp code. | 2424 // Process the result from the native regexp code. |
2387 __ bind(&success); | 2425 __ bind(&success); |
2388 __ LoadP(r4, | 2426 __ LoadP(r4, |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 __ SmiToPtrArrayOffset(r7, r6); | 2874 __ SmiToPtrArrayOffset(r7, r6); |
2837 __ add(r7, r5, r7); | 2875 __ add(r7, r5, r7); |
2838 __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize)); | 2876 __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize)); |
2839 | 2877 |
2840 // Verify that r7 contains an AllocationSite | 2878 // Verify that r7 contains an AllocationSite |
2841 __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset)); | 2879 __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset)); |
2842 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); | 2880 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); |
2843 __ bne(&miss); | 2881 __ bne(&miss); |
2844 | 2882 |
2845 __ mr(r5, r7); | 2883 __ mr(r5, r7); |
| 2884 __ mr(r6, r4); |
2846 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2885 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
2847 __ TailCallStub(&stub); | 2886 __ TailCallStub(&stub); |
2848 | 2887 |
2849 __ bind(&miss); | 2888 __ bind(&miss); |
2850 GenerateMiss(masm); | 2889 GenerateMiss(masm); |
2851 | 2890 |
2852 // The slow case, we need this no matter what to complete a call after a miss. | 2891 // The slow case, we need this no matter what to complete a call after a miss. |
2853 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | 2892 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); |
2854 | 2893 |
2855 // Unreachable. | 2894 // Unreachable. |
(...skipping 1959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4815 UNREACHABLE(); | 4854 UNREACHABLE(); |
4816 } | 4855 } |
4817 } | 4856 } |
4818 | 4857 |
4819 | 4858 |
4820 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 4859 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
4821 // ----------- S t a t e ------------- | 4860 // ----------- S t a t e ------------- |
4822 // -- r3 : argc (only if argument_count() == ANY) | 4861 // -- r3 : argc (only if argument_count() == ANY) |
4823 // -- r4 : constructor | 4862 // -- r4 : constructor |
4824 // -- r5 : AllocationSite or undefined | 4863 // -- r5 : AllocationSite or undefined |
| 4864 // -- r6 : original constructor |
4825 // -- sp[0] : return address | 4865 // -- sp[0] : return address |
4826 // -- sp[4] : last argument | 4866 // -- sp[4] : last argument |
4827 // ----------------------------------- | 4867 // ----------------------------------- |
4828 | 4868 |
4829 if (FLAG_debug_code) { | 4869 if (FLAG_debug_code) { |
4830 // The array construct code is only set for the global and natives | 4870 // The array construct code is only set for the global and natives |
4831 // builtin Array functions which always have maps. | 4871 // builtin Array functions which always have maps. |
4832 | 4872 |
4833 // Initial map for the builtin Array function should be a map. | 4873 // Initial map for the builtin Array function should be a map. |
4834 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset)); | 4874 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset)); |
4835 // Will both indicate a NULL and a Smi. | 4875 // Will both indicate a NULL and a Smi. |
4836 __ TestIfSmi(r7, r0); | 4876 __ TestIfSmi(r7, r0); |
4837 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0); | 4877 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0); |
4838 __ CompareObjectType(r7, r7, r8, MAP_TYPE); | 4878 __ CompareObjectType(r7, r7, r8, MAP_TYPE); |
4839 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); | 4879 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); |
4840 | 4880 |
4841 // We should either have undefined in r5 or a valid AllocationSite | 4881 // We should either have undefined in r5 or a valid AllocationSite |
4842 __ AssertUndefinedOrAllocationSite(r5, r7); | 4882 __ AssertUndefinedOrAllocationSite(r5, r7); |
4843 } | 4883 } |
4844 | 4884 |
| 4885 Label subclassing; |
| 4886 __ cmp(r6, r4); |
| 4887 __ bne(&subclassing); |
| 4888 |
4845 Label no_info; | 4889 Label no_info; |
4846 // Get the elements kind and case on that. | 4890 // Get the elements kind and case on that. |
4847 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); | 4891 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); |
4848 __ beq(&no_info); | 4892 __ beq(&no_info); |
4849 | 4893 |
4850 __ LoadP(r6, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); | 4894 __ LoadP(r6, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); |
4851 __ SmiUntag(r6); | 4895 __ SmiUntag(r6); |
4852 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 4896 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
4853 __ And(r6, r6, Operand(AllocationSite::ElementsKindBits::kMask)); | 4897 __ And(r6, r6, Operand(AllocationSite::ElementsKindBits::kMask)); |
4854 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 4898 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
4855 | 4899 |
4856 __ bind(&no_info); | 4900 __ bind(&no_info); |
4857 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 4901 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 4902 |
| 4903 __ bind(&subclassing); |
| 4904 __ push(r4); |
| 4905 __ push(r6); |
| 4906 |
| 4907 // Adjust argc. |
| 4908 switch (argument_count()) { |
| 4909 case ANY: |
| 4910 case MORE_THAN_ONE: |
| 4911 __ addi(r3, r3, Operand(2)); |
| 4912 break; |
| 4913 case NONE: |
| 4914 __ li(r3, Operand(2)); |
| 4915 break; |
| 4916 case ONE: |
| 4917 __ li(r3, Operand(3)); |
| 4918 break; |
| 4919 } |
| 4920 |
| 4921 __ JumpToExternalReference( |
| 4922 ExternalReference(Runtime::kArrayConstructorWithSubclassing, isolate())); |
4858 } | 4923 } |
4859 | 4924 |
4860 | 4925 |
4861 void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm, | 4926 void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm, |
4862 ElementsKind kind) { | 4927 ElementsKind kind) { |
4863 __ cmpli(r3, Operand(1)); | 4928 __ cmpli(r3, Operand(1)); |
4864 | 4929 |
4865 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind); | 4930 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind); |
4866 __ TailCallStub(&stub0, lt); | 4931 __ TailCallStub(&stub0, lt); |
4867 | 4932 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5010 FrameScope frame(masm, StackFrame::MANUAL); | 5075 FrameScope frame(masm, StackFrame::MANUAL); |
5011 __ PushSafepointRegisters(); | 5076 __ PushSafepointRegisters(); |
5012 __ PrepareCallCFunction(1, r3); | 5077 __ PrepareCallCFunction(1, r3); |
5013 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); | 5078 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); |
5014 __ CallCFunction(ExternalReference::log_leave_external_function(isolate), | 5079 __ CallCFunction(ExternalReference::log_leave_external_function(isolate), |
5015 1); | 5080 1); |
5016 __ PopSafepointRegisters(); | 5081 __ PopSafepointRegisters(); |
5017 } | 5082 } |
5018 | 5083 |
5019 Label promote_scheduled_exception; | 5084 Label promote_scheduled_exception; |
5020 Label exception_handled; | |
5021 Label delete_allocated_handles; | 5085 Label delete_allocated_handles; |
5022 Label leave_exit_frame; | 5086 Label leave_exit_frame; |
5023 Label return_value_loaded; | 5087 Label return_value_loaded; |
5024 | 5088 |
5025 // load value from ReturnValue | 5089 // load value from ReturnValue |
5026 __ LoadP(r3, return_value_operand); | 5090 __ LoadP(r3, return_value_operand); |
5027 __ bind(&return_value_loaded); | 5091 __ bind(&return_value_loaded); |
5028 // No more valid handles (the result handle was the last one). Restore | 5092 // No more valid handles (the result handle was the last one). Restore |
5029 // previous handle scope. | 5093 // previous handle scope. |
5030 __ StoreP(r14, MemOperand(r17, kNextOffset)); | 5094 __ StoreP(r14, MemOperand(r17, kNextOffset)); |
5031 if (__ emit_debug_code()) { | 5095 if (__ emit_debug_code()) { |
5032 __ lwz(r4, MemOperand(r17, kLevelOffset)); | 5096 __ lwz(r4, MemOperand(r17, kLevelOffset)); |
5033 __ cmp(r4, r16); | 5097 __ cmp(r4, r16); |
5034 __ Check(eq, kUnexpectedLevelAfterReturnFromApiCall); | 5098 __ Check(eq, kUnexpectedLevelAfterReturnFromApiCall); |
5035 } | 5099 } |
5036 __ subi(r16, r16, Operand(1)); | 5100 __ subi(r16, r16, Operand(1)); |
5037 __ stw(r16, MemOperand(r17, kLevelOffset)); | 5101 __ stw(r16, MemOperand(r17, kLevelOffset)); |
5038 __ LoadP(r0, MemOperand(r17, kLimitOffset)); | 5102 __ LoadP(r0, MemOperand(r17, kLimitOffset)); |
5039 __ cmp(r15, r0); | 5103 __ cmp(r15, r0); |
5040 __ bne(&delete_allocated_handles); | 5104 __ bne(&delete_allocated_handles); |
5041 | 5105 |
5042 // Check if the function scheduled an exception. | 5106 // Leave the API exit frame. |
5043 __ bind(&leave_exit_frame); | 5107 __ bind(&leave_exit_frame); |
5044 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); | |
5045 __ mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate))); | |
5046 __ LoadP(r15, MemOperand(r15)); | |
5047 __ cmp(r14, r15); | |
5048 __ bne(&promote_scheduled_exception); | |
5049 __ bind(&exception_handled); | |
5050 | |
5051 bool restore_context = context_restore_operand != NULL; | 5108 bool restore_context = context_restore_operand != NULL; |
5052 if (restore_context) { | 5109 if (restore_context) { |
5053 __ LoadP(cp, *context_restore_operand); | 5110 __ LoadP(cp, *context_restore_operand); |
5054 } | 5111 } |
5055 // LeaveExitFrame expects unwind space to be in a register. | 5112 // LeaveExitFrame expects unwind space to be in a register. |
5056 if (stack_space_operand != NULL) { | 5113 if (stack_space_operand != NULL) { |
5057 __ lwz(r14, *stack_space_operand); | 5114 __ lwz(r14, *stack_space_operand); |
5058 } else { | 5115 } else { |
5059 __ mov(r14, Operand(stack_space)); | 5116 __ mov(r14, Operand(stack_space)); |
5060 } | 5117 } |
5061 __ LeaveExitFrame(false, r14, !restore_context, stack_space_operand != NULL); | 5118 __ LeaveExitFrame(false, r14, !restore_context, stack_space_operand != NULL); |
| 5119 |
| 5120 // Check if the function scheduled an exception. |
| 5121 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
| 5122 __ mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate))); |
| 5123 __ LoadP(r15, MemOperand(r15)); |
| 5124 __ cmp(r14, r15); |
| 5125 __ bne(&promote_scheduled_exception); |
| 5126 |
5062 __ blr(); | 5127 __ blr(); |
5063 | 5128 |
| 5129 // Re-throw by promoting a scheduled exception. |
5064 __ bind(&promote_scheduled_exception); | 5130 __ bind(&promote_scheduled_exception); |
5065 { | 5131 __ TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
5066 FrameScope frame(masm, StackFrame::INTERNAL); | |
5067 __ CallExternalReference( | |
5068 ExternalReference(Runtime::kPromoteScheduledException, isolate), 0); | |
5069 } | |
5070 __ jmp(&exception_handled); | |
5071 | 5132 |
5072 // HandleScope limit has changed. Delete allocated extensions. | 5133 // HandleScope limit has changed. Delete allocated extensions. |
5073 __ bind(&delete_allocated_handles); | 5134 __ bind(&delete_allocated_handles); |
5074 __ StoreP(r15, MemOperand(r17, kLimitOffset)); | 5135 __ StoreP(r15, MemOperand(r17, kLimitOffset)); |
5075 __ mr(r14, r3); | 5136 __ mr(r14, r3); |
5076 __ PrepareCallCFunction(1, r15); | 5137 __ PrepareCallCFunction(1, r15); |
5077 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); | 5138 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); |
5078 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), | 5139 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), |
5079 1); | 5140 1); |
5080 __ mr(r3, r14); | 5141 __ mr(r3, r14); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5292 kStackUnwindSpace, NULL, | 5353 kStackUnwindSpace, NULL, |
5293 MemOperand(fp, 6 * kPointerSize), NULL); | 5354 MemOperand(fp, 6 * kPointerSize), NULL); |
5294 } | 5355 } |
5295 | 5356 |
5296 | 5357 |
5297 #undef __ | 5358 #undef __ |
5298 } | 5359 } |
5299 } // namespace v8::internal | 5360 } // namespace v8::internal |
5300 | 5361 |
5301 #endif // V8_TARGET_ARCH_PPC | 5362 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |