| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 __ bne(&okay); | 1146 __ bne(&okay); |
| 1093 __ stop("The hole escaped"); | 1147 __ stop("The hole escaped"); |
| 1094 __ bind(&okay); | 1148 __ bind(&okay); |
| 1095 } | 1149 } |
| 1096 | 1150 |
| 1097 // Check result for exception sentinel. | 1151 // Check result for exception sentinel. |
| 1098 Label exception_returned; | 1152 Label exception_returned; |
| 1099 __ CompareRoot(r3, Heap::kExceptionRootIndex); | 1153 __ CompareRoot(r3, Heap::kExceptionRootIndex); |
| 1100 __ beq(&exception_returned); | 1154 __ beq(&exception_returned); |
| 1101 | 1155 |
| 1102 ExternalReference pending_exception_address(Isolate::kPendingExceptionAddress, | |
| 1103 isolate()); | |
| 1104 | |
| 1105 // Check that there is no pending exception, otherwise we | 1156 // Check that there is no pending exception, otherwise we |
| 1106 // should have returned the exception sentinel. | 1157 // should have returned the exception sentinel. |
| 1107 if (FLAG_debug_code) { | 1158 if (FLAG_debug_code) { |
| 1108 Label okay; | 1159 Label okay; |
| 1160 ExternalReference pending_exception_address( |
| 1161 Isolate::kPendingExceptionAddress, isolate()); |
| 1162 |
| 1109 __ mov(r5, Operand(pending_exception_address)); | 1163 __ mov(r5, Operand(pending_exception_address)); |
| 1110 __ LoadP(r5, MemOperand(r5)); | 1164 __ LoadP(r5, MemOperand(r5)); |
| 1111 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 1165 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); |
| 1112 // Cannot use check here as it attempts to generate call into runtime. | 1166 // Cannot use check here as it attempts to generate call into runtime. |
| 1113 __ beq(&okay); | 1167 __ beq(&okay); |
| 1114 __ stop("Unexpected pending exception"); | 1168 __ stop("Unexpected pending exception"); |
| 1115 __ bind(&okay); | 1169 __ bind(&okay); |
| 1116 } | 1170 } |
| 1117 | 1171 |
| 1118 // Exit C frame and return. | 1172 // Exit C frame and return. |
| 1119 // r3:r4: result | 1173 // r3:r4: result |
| 1120 // sp: stack pointer | 1174 // sp: stack pointer |
| 1121 // fp: frame pointer | 1175 // fp: frame pointer |
| 1122 // r14: still holds argc (callee-saved). | 1176 // r14: still holds argc (callee-saved). |
| 1123 __ LeaveExitFrame(save_doubles(), r14, true); | 1177 __ LeaveExitFrame(save_doubles(), r14, true); |
| 1124 __ blr(); | 1178 __ blr(); |
| 1125 | 1179 |
| 1126 // Handling of exception. | 1180 // Handling of exception. |
| 1127 __ bind(&exception_returned); | 1181 __ bind(&exception_returned); |
| 1128 | 1182 |
| 1129 // Retrieve the pending exception. | 1183 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 } | 1184 } |
| 1149 | 1185 |
| 1150 | 1186 |
| 1151 void JSEntryStub::Generate(MacroAssembler* masm) { | 1187 void JSEntryStub::Generate(MacroAssembler* masm) { |
| 1152 // r3: code entry | 1188 // r3: code entry |
| 1153 // r4: function | 1189 // r4: function |
| 1154 // r5: receiver | 1190 // r5: receiver |
| 1155 // r6: argc | 1191 // r6: argc |
| 1156 // [sp+0]: argv | 1192 // [sp+0]: argv |
| 1157 | 1193 |
| (...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 | 2393 // 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. | 2394 // haven't created the exception yet. Handle that in the runtime system. |
| 2359 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2395 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
| 2360 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); | 2396 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); |
| 2361 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2397 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 2362 isolate()))); | 2398 isolate()))); |
| 2363 __ LoadP(r3, MemOperand(r5, 0)); | 2399 __ LoadP(r3, MemOperand(r5, 0)); |
| 2364 __ cmp(r3, r4); | 2400 __ cmp(r3, r4); |
| 2365 __ beq(&runtime); | 2401 __ beq(&runtime); |
| 2366 | 2402 |
| 2367 __ StoreP(r4, MemOperand(r5, 0)); // Clear pending exception. | 2403 // For exception, throw the exception again. |
| 2368 | 2404 __ EnterExitFrame(false); |
| 2369 // Check if the exception is a termination. If so, throw as uncatchable. | 2405 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 | 2406 |
| 2380 __ bind(&failure); | 2407 __ bind(&failure); |
| 2381 // For failure and exception return null. | 2408 // For failure and exception return null. |
| 2382 __ mov(r3, Operand(isolate()->factory()->null_value())); | 2409 __ mov(r3, Operand(isolate()->factory()->null_value())); |
| 2383 __ addi(sp, sp, Operand(4 * kPointerSize)); | 2410 __ addi(sp, sp, Operand(4 * kPointerSize)); |
| 2384 __ Ret(); | 2411 __ Ret(); |
| 2385 | 2412 |
| 2386 // Process the result from the native regexp code. | 2413 // Process the result from the native regexp code. |
| 2387 __ bind(&success); | 2414 __ bind(&success); |
| 2388 __ LoadP(r4, | 2415 __ LoadP(r4, |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2836 __ SmiToPtrArrayOffset(r7, r6); | 2863 __ SmiToPtrArrayOffset(r7, r6); |
| 2837 __ add(r7, r5, r7); | 2864 __ add(r7, r5, r7); |
| 2838 __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize)); | 2865 __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize)); |
| 2839 | 2866 |
| 2840 // Verify that r7 contains an AllocationSite | 2867 // Verify that r7 contains an AllocationSite |
| 2841 __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset)); | 2868 __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset)); |
| 2842 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); | 2869 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); |
| 2843 __ bne(&miss); | 2870 __ bne(&miss); |
| 2844 | 2871 |
| 2845 __ mr(r5, r7); | 2872 __ mr(r5, r7); |
| 2873 __ mr(r6, r4); |
| 2846 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2874 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2847 __ TailCallStub(&stub); | 2875 __ TailCallStub(&stub); |
| 2848 | 2876 |
| 2849 __ bind(&miss); | 2877 __ bind(&miss); |
| 2850 GenerateMiss(masm); | 2878 GenerateMiss(masm); |
| 2851 | 2879 |
| 2852 // The slow case, we need this no matter what to complete a call after a miss. | 2880 // The slow case, we need this no matter what to complete a call after a miss. |
| 2853 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | 2881 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); |
| 2854 | 2882 |
| 2855 // Unreachable. | 2883 // Unreachable. |
| (...skipping 1959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4815 UNREACHABLE(); | 4843 UNREACHABLE(); |
| 4816 } | 4844 } |
| 4817 } | 4845 } |
| 4818 | 4846 |
| 4819 | 4847 |
| 4820 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 4848 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 4821 // ----------- S t a t e ------------- | 4849 // ----------- S t a t e ------------- |
| 4822 // -- r3 : argc (only if argument_count() == ANY) | 4850 // -- r3 : argc (only if argument_count() == ANY) |
| 4823 // -- r4 : constructor | 4851 // -- r4 : constructor |
| 4824 // -- r5 : AllocationSite or undefined | 4852 // -- r5 : AllocationSite or undefined |
| 4853 // -- r6 : original constructor |
| 4825 // -- sp[0] : return address | 4854 // -- sp[0] : return address |
| 4826 // -- sp[4] : last argument | 4855 // -- sp[4] : last argument |
| 4827 // ----------------------------------- | 4856 // ----------------------------------- |
| 4828 | 4857 |
| 4829 if (FLAG_debug_code) { | 4858 if (FLAG_debug_code) { |
| 4830 // The array construct code is only set for the global and natives | 4859 // The array construct code is only set for the global and natives |
| 4831 // builtin Array functions which always have maps. | 4860 // builtin Array functions which always have maps. |
| 4832 | 4861 |
| 4833 // Initial map for the builtin Array function should be a map. | 4862 // Initial map for the builtin Array function should be a map. |
| 4834 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset)); | 4863 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset)); |
| 4835 // Will both indicate a NULL and a Smi. | 4864 // Will both indicate a NULL and a Smi. |
| 4836 __ TestIfSmi(r7, r0); | 4865 __ TestIfSmi(r7, r0); |
| 4837 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0); | 4866 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0); |
| 4838 __ CompareObjectType(r7, r7, r8, MAP_TYPE); | 4867 __ CompareObjectType(r7, r7, r8, MAP_TYPE); |
| 4839 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); | 4868 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); |
| 4840 | 4869 |
| 4841 // We should either have undefined in r5 or a valid AllocationSite | 4870 // We should either have undefined in r5 or a valid AllocationSite |
| 4842 __ AssertUndefinedOrAllocationSite(r5, r7); | 4871 __ AssertUndefinedOrAllocationSite(r5, r7); |
| 4843 } | 4872 } |
| 4844 | 4873 |
| 4874 Label subclassing; |
| 4875 __ cmp(r6, r4); |
| 4876 __ bne(&subclassing); |
| 4877 |
| 4845 Label no_info; | 4878 Label no_info; |
| 4846 // Get the elements kind and case on that. | 4879 // Get the elements kind and case on that. |
| 4847 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); | 4880 __ CompareRoot(r5, Heap::kUndefinedValueRootIndex); |
| 4848 __ beq(&no_info); | 4881 __ beq(&no_info); |
| 4849 | 4882 |
| 4850 __ LoadP(r6, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); | 4883 __ LoadP(r6, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset)); |
| 4851 __ SmiUntag(r6); | 4884 __ SmiUntag(r6); |
| 4852 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 4885 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
| 4853 __ And(r6, r6, Operand(AllocationSite::ElementsKindBits::kMask)); | 4886 __ And(r6, r6, Operand(AllocationSite::ElementsKindBits::kMask)); |
| 4854 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 4887 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 4855 | 4888 |
| 4856 __ bind(&no_info); | 4889 __ bind(&no_info); |
| 4857 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 4890 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 4891 |
| 4892 __ bind(&subclassing); |
| 4893 __ push(r4); |
| 4894 __ push(r6); |
| 4895 |
| 4896 // Adjust argc. |
| 4897 switch (argument_count()) { |
| 4898 case ANY: |
| 4899 case MORE_THAN_ONE: |
| 4900 __ addi(r3, r3, Operand(2)); |
| 4901 break; |
| 4902 case NONE: |
| 4903 __ li(r3, Operand(2)); |
| 4904 break; |
| 4905 case ONE: |
| 4906 __ li(r3, Operand(3)); |
| 4907 break; |
| 4908 } |
| 4909 |
| 4910 __ JumpToExternalReference( |
| 4911 ExternalReference(Runtime::kArrayConstructorWithSubclassing, isolate())); |
| 4858 } | 4912 } |
| 4859 | 4913 |
| 4860 | 4914 |
| 4861 void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm, | 4915 void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm, |
| 4862 ElementsKind kind) { | 4916 ElementsKind kind) { |
| 4863 __ cmpli(r3, Operand(1)); | 4917 __ cmpli(r3, Operand(1)); |
| 4864 | 4918 |
| 4865 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind); | 4919 InternalArrayNoArgumentConstructorStub stub0(isolate(), kind); |
| 4866 __ TailCallStub(&stub0, lt); | 4920 __ TailCallStub(&stub0, lt); |
| 4867 | 4921 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5010 FrameScope frame(masm, StackFrame::MANUAL); | 5064 FrameScope frame(masm, StackFrame::MANUAL); |
| 5011 __ PushSafepointRegisters(); | 5065 __ PushSafepointRegisters(); |
| 5012 __ PrepareCallCFunction(1, r3); | 5066 __ PrepareCallCFunction(1, r3); |
| 5013 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); | 5067 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); |
| 5014 __ CallCFunction(ExternalReference::log_leave_external_function(isolate), | 5068 __ CallCFunction(ExternalReference::log_leave_external_function(isolate), |
| 5015 1); | 5069 1); |
| 5016 __ PopSafepointRegisters(); | 5070 __ PopSafepointRegisters(); |
| 5017 } | 5071 } |
| 5018 | 5072 |
| 5019 Label promote_scheduled_exception; | 5073 Label promote_scheduled_exception; |
| 5020 Label exception_handled; | |
| 5021 Label delete_allocated_handles; | 5074 Label delete_allocated_handles; |
| 5022 Label leave_exit_frame; | 5075 Label leave_exit_frame; |
| 5023 Label return_value_loaded; | 5076 Label return_value_loaded; |
| 5024 | 5077 |
| 5025 // load value from ReturnValue | 5078 // load value from ReturnValue |
| 5026 __ LoadP(r3, return_value_operand); | 5079 __ LoadP(r3, return_value_operand); |
| 5027 __ bind(&return_value_loaded); | 5080 __ bind(&return_value_loaded); |
| 5028 // No more valid handles (the result handle was the last one). Restore | 5081 // No more valid handles (the result handle was the last one). Restore |
| 5029 // previous handle scope. | 5082 // previous handle scope. |
| 5030 __ StoreP(r14, MemOperand(r17, kNextOffset)); | 5083 __ StoreP(r14, MemOperand(r17, kNextOffset)); |
| 5031 if (__ emit_debug_code()) { | 5084 if (__ emit_debug_code()) { |
| 5032 __ lwz(r4, MemOperand(r17, kLevelOffset)); | 5085 __ lwz(r4, MemOperand(r17, kLevelOffset)); |
| 5033 __ cmp(r4, r16); | 5086 __ cmp(r4, r16); |
| 5034 __ Check(eq, kUnexpectedLevelAfterReturnFromApiCall); | 5087 __ Check(eq, kUnexpectedLevelAfterReturnFromApiCall); |
| 5035 } | 5088 } |
| 5036 __ subi(r16, r16, Operand(1)); | 5089 __ subi(r16, r16, Operand(1)); |
| 5037 __ stw(r16, MemOperand(r17, kLevelOffset)); | 5090 __ stw(r16, MemOperand(r17, kLevelOffset)); |
| 5038 __ LoadP(r0, MemOperand(r17, kLimitOffset)); | 5091 __ LoadP(r0, MemOperand(r17, kLimitOffset)); |
| 5039 __ cmp(r15, r0); | 5092 __ cmp(r15, r0); |
| 5040 __ bne(&delete_allocated_handles); | 5093 __ bne(&delete_allocated_handles); |
| 5041 | 5094 |
| 5042 // Check if the function scheduled an exception. | 5095 // Leave the API exit frame. |
| 5043 __ bind(&leave_exit_frame); | 5096 __ 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; | 5097 bool restore_context = context_restore_operand != NULL; |
| 5052 if (restore_context) { | 5098 if (restore_context) { |
| 5053 __ LoadP(cp, *context_restore_operand); | 5099 __ LoadP(cp, *context_restore_operand); |
| 5054 } | 5100 } |
| 5055 // LeaveExitFrame expects unwind space to be in a register. | 5101 // LeaveExitFrame expects unwind space to be in a register. |
| 5056 if (stack_space_operand != NULL) { | 5102 if (stack_space_operand != NULL) { |
| 5057 __ lwz(r14, *stack_space_operand); | 5103 __ lwz(r14, *stack_space_operand); |
| 5058 } else { | 5104 } else { |
| 5059 __ mov(r14, Operand(stack_space)); | 5105 __ mov(r14, Operand(stack_space)); |
| 5060 } | 5106 } |
| 5061 __ LeaveExitFrame(false, r14, !restore_context, stack_space_operand != NULL); | 5107 __ LeaveExitFrame(false, r14, !restore_context, stack_space_operand != NULL); |
| 5108 |
| 5109 // Check if the function scheduled an exception. |
| 5110 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
| 5111 __ mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate))); |
| 5112 __ LoadP(r15, MemOperand(r15)); |
| 5113 __ cmp(r14, r15); |
| 5114 __ bne(&promote_scheduled_exception); |
| 5115 |
| 5062 __ blr(); | 5116 __ blr(); |
| 5063 | 5117 |
| 5118 // Re-throw by promoting a scheduled exception. |
| 5064 __ bind(&promote_scheduled_exception); | 5119 __ bind(&promote_scheduled_exception); |
| 5065 { | 5120 __ 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 | 5121 |
| 5072 // HandleScope limit has changed. Delete allocated extensions. | 5122 // HandleScope limit has changed. Delete allocated extensions. |
| 5073 __ bind(&delete_allocated_handles); | 5123 __ bind(&delete_allocated_handles); |
| 5074 __ StoreP(r15, MemOperand(r17, kLimitOffset)); | 5124 __ StoreP(r15, MemOperand(r17, kLimitOffset)); |
| 5075 __ mr(r14, r3); | 5125 __ mr(r14, r3); |
| 5076 __ PrepareCallCFunction(1, r15); | 5126 __ PrepareCallCFunction(1, r15); |
| 5077 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); | 5127 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); |
| 5078 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), | 5128 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), |
| 5079 1); | 5129 1); |
| 5080 __ mr(r3, r14); | 5130 __ mr(r3, r14); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5292 kStackUnwindSpace, NULL, | 5342 kStackUnwindSpace, NULL, |
| 5293 MemOperand(fp, 6 * kPointerSize), NULL); | 5343 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5294 } | 5344 } |
| 5295 | 5345 |
| 5296 | 5346 |
| 5297 #undef __ | 5347 #undef __ |
| 5298 } | 5348 } |
| 5299 } // namespace v8::internal | 5349 } // namespace v8::internal |
| 5300 | 5350 |
| 5301 #endif // V8_TARGET_ARCH_PPC | 5351 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |