| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 orr(scratch, scratch, Operand(ip, LSL, address)); | 454 orr(scratch, scratch, Operand(ip, LSL, address)); |
| 455 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); | 455 str(scratch, MemOperand(object, Page::kDirtyFlagOffset)); |
| 456 } | 456 } |
| 457 | 457 |
| 458 | 458 |
| 459 void MacroAssembler::InNewSpace(Register object, | 459 void MacroAssembler::InNewSpace(Register object, |
| 460 Register scratch, | 460 Register scratch, |
| 461 Condition cond, | 461 Condition cond, |
| 462 Label* branch) { | 462 Label* branch) { |
| 463 ASSERT(cond == eq || cond == ne); | 463 ASSERT(cond == eq || cond == ne); |
| 464 and_(scratch, object, Operand(ExternalReference::new_space_mask())); | 464 and_(scratch, object, Operand(ExternalReference::new_space_mask(isolate()))); |
| 465 cmp(scratch, Operand(ExternalReference::new_space_start())); | 465 cmp(scratch, Operand(ExternalReference::new_space_start(isolate()))); |
| 466 b(cond, branch); | 466 b(cond, branch); |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 // Will clobber 4 registers: object, offset, scratch, ip. The | 470 // Will clobber 4 registers: object, offset, scratch, ip. The |
| 471 // register 'object' contains a heap object pointer. The heap object | 471 // register 'object' contains a heap object pointer. The heap object |
| 472 // tag is shifted away. | 472 // tag is shifted away. |
| 473 void MacroAssembler::RecordWrite(Register object, | 473 void MacroAssembler::RecordWrite(Register object, |
| 474 Operand offset, | 474 Operand offset, |
| 475 Register scratch0, | 475 Register scratch0, |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 // Reserve room for saved entry sp and code object. | 732 // Reserve room for saved entry sp and code object. |
| 733 sub(sp, sp, Operand(2 * kPointerSize)); | 733 sub(sp, sp, Operand(2 * kPointerSize)); |
| 734 if (emit_debug_code()) { | 734 if (emit_debug_code()) { |
| 735 mov(ip, Operand(0)); | 735 mov(ip, Operand(0)); |
| 736 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 736 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 737 } | 737 } |
| 738 mov(ip, Operand(CodeObject())); | 738 mov(ip, Operand(CodeObject())); |
| 739 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 739 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
| 740 | 740 |
| 741 // Save the frame pointer and the context in top. | 741 // Save the frame pointer and the context in top. |
| 742 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address))); | 742 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); |
| 743 str(fp, MemOperand(ip)); | 743 str(fp, MemOperand(ip)); |
| 744 mov(ip, Operand(ExternalReference(Isolate::k_context_address))); | 744 mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); |
| 745 str(cp, MemOperand(ip)); | 745 str(cp, MemOperand(ip)); |
| 746 | 746 |
| 747 // Optionally save all double registers. | 747 // Optionally save all double registers. |
| 748 if (save_doubles) { | 748 if (save_doubles) { |
| 749 sub(sp, sp, Operand(DwVfpRegister::kNumRegisters * kDoubleSize)); | 749 sub(sp, sp, Operand(DwVfpRegister::kNumRegisters * kDoubleSize)); |
| 750 const int offset = -2 * kPointerSize; | 750 const int offset = -2 * kPointerSize; |
| 751 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { | 751 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { |
| 752 DwVfpRegister reg = DwVfpRegister::from_code(i); | 752 DwVfpRegister reg = DwVfpRegister::from_code(i); |
| 753 vstr(reg, fp, offset - ((i + 1) * kDoubleSize)); | 753 vstr(reg, fp, offset - ((i + 1) * kDoubleSize)); |
| 754 } | 754 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 if (save_doubles) { | 810 if (save_doubles) { |
| 811 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { | 811 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { |
| 812 DwVfpRegister reg = DwVfpRegister::from_code(i); | 812 DwVfpRegister reg = DwVfpRegister::from_code(i); |
| 813 const int offset = -2 * kPointerSize; | 813 const int offset = -2 * kPointerSize; |
| 814 vldr(reg, fp, offset - ((i + 1) * kDoubleSize)); | 814 vldr(reg, fp, offset - ((i + 1) * kDoubleSize)); |
| 815 } | 815 } |
| 816 } | 816 } |
| 817 | 817 |
| 818 // Clear top frame. | 818 // Clear top frame. |
| 819 mov(r3, Operand(0, RelocInfo::NONE)); | 819 mov(r3, Operand(0, RelocInfo::NONE)); |
| 820 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address))); | 820 mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); |
| 821 str(r3, MemOperand(ip)); | 821 str(r3, MemOperand(ip)); |
| 822 | 822 |
| 823 // Restore current context from top and clear it in debug mode. | 823 // Restore current context from top and clear it in debug mode. |
| 824 mov(ip, Operand(ExternalReference(Isolate::k_context_address))); | 824 mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); |
| 825 ldr(cp, MemOperand(ip)); | 825 ldr(cp, MemOperand(ip)); |
| 826 #ifdef DEBUG | 826 #ifdef DEBUG |
| 827 str(r3, MemOperand(ip)); | 827 str(r3, MemOperand(ip)); |
| 828 #endif | 828 #endif |
| 829 | 829 |
| 830 // Tear down the exit frame, pop the arguments, and return. | 830 // Tear down the exit frame, pop the arguments, and return. |
| 831 mov(sp, Operand(fp)); | 831 mov(sp, Operand(fp)); |
| 832 ldm(ia_w, sp, fp.bit() | lr.bit()); | 832 ldm(ia_w, sp, fp.bit() | lr.bit()); |
| 833 if (argument_count.is_valid()) { | 833 if (argument_count.is_valid()) { |
| 834 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2)); | 834 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2)); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 1041 ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); |
| 1042 tst(scratch, Operand(kIsNotStringMask)); | 1042 tst(scratch, Operand(kIsNotStringMask)); |
| 1043 b(ne, fail); | 1043 b(ne, fail); |
| 1044 } | 1044 } |
| 1045 | 1045 |
| 1046 | 1046 |
| 1047 #ifdef ENABLE_DEBUGGER_SUPPORT | 1047 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1048 void MacroAssembler::DebugBreak() { | 1048 void MacroAssembler::DebugBreak() { |
| 1049 ASSERT(allow_stub_calls()); | 1049 ASSERT(allow_stub_calls()); |
| 1050 mov(r0, Operand(0, RelocInfo::NONE)); | 1050 mov(r0, Operand(0, RelocInfo::NONE)); |
| 1051 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak))); | 1051 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
| 1052 CEntryStub ces(1); | 1052 CEntryStub ces(1); |
| 1053 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1053 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
| 1054 } | 1054 } |
| 1055 #endif | 1055 #endif |
| 1056 | 1056 |
| 1057 | 1057 |
| 1058 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 1058 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 1059 HandlerType type) { | 1059 HandlerType type) { |
| 1060 // Adjust this code if not the case. | 1060 // Adjust this code if not the case. |
| 1061 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 1061 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
| 1062 // The pc (return address) is passed in register lr. | 1062 // The pc (return address) is passed in register lr. |
| 1063 if (try_location == IN_JAVASCRIPT) { | 1063 if (try_location == IN_JAVASCRIPT) { |
| 1064 if (type == TRY_CATCH_HANDLER) { | 1064 if (type == TRY_CATCH_HANDLER) { |
| 1065 mov(r3, Operand(StackHandler::TRY_CATCH)); | 1065 mov(r3, Operand(StackHandler::TRY_CATCH)); |
| 1066 } else { | 1066 } else { |
| 1067 mov(r3, Operand(StackHandler::TRY_FINALLY)); | 1067 mov(r3, Operand(StackHandler::TRY_FINALLY)); |
| 1068 } | 1068 } |
| 1069 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize | 1069 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize |
| 1070 && StackHandlerConstants::kFPOffset == 2 * kPointerSize | 1070 && StackHandlerConstants::kFPOffset == 2 * kPointerSize |
| 1071 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 1071 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 1072 stm(db_w, sp, r3.bit() | fp.bit() | lr.bit()); | 1072 stm(db_w, sp, r3.bit() | fp.bit() | lr.bit()); |
| 1073 // Save the current handler as the next handler. | 1073 // Save the current handler as the next handler. |
| 1074 mov(r3, Operand(ExternalReference(Isolate::k_handler_address))); | 1074 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1075 ldr(r1, MemOperand(r3)); | 1075 ldr(r1, MemOperand(r3)); |
| 1076 ASSERT(StackHandlerConstants::kNextOffset == 0); | 1076 ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 1077 push(r1); | 1077 push(r1); |
| 1078 // Link this handler as the new current one. | 1078 // Link this handler as the new current one. |
| 1079 str(sp, MemOperand(r3)); | 1079 str(sp, MemOperand(r3)); |
| 1080 } else { | 1080 } else { |
| 1081 // Must preserve r0-r4, r5-r7 are available. | 1081 // Must preserve r0-r4, r5-r7 are available. |
| 1082 ASSERT(try_location == IN_JS_ENTRY); | 1082 ASSERT(try_location == IN_JS_ENTRY); |
| 1083 // The frame pointer does not point to a JS frame so we save NULL | 1083 // The frame pointer does not point to a JS frame so we save NULL |
| 1084 // for fp. We expect the code throwing an exception to check fp | 1084 // for fp. We expect the code throwing an exception to check fp |
| 1085 // before dereferencing it to restore the context. | 1085 // before dereferencing it to restore the context. |
| 1086 mov(ip, Operand(0, RelocInfo::NONE)); // To save a NULL frame pointer. | 1086 mov(ip, Operand(0, RelocInfo::NONE)); // To save a NULL frame pointer. |
| 1087 mov(r6, Operand(StackHandler::ENTRY)); | 1087 mov(r6, Operand(StackHandler::ENTRY)); |
| 1088 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize | 1088 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize |
| 1089 && StackHandlerConstants::kFPOffset == 2 * kPointerSize | 1089 && StackHandlerConstants::kFPOffset == 2 * kPointerSize |
| 1090 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); | 1090 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
| 1091 stm(db_w, sp, r6.bit() | ip.bit() | lr.bit()); | 1091 stm(db_w, sp, r6.bit() | ip.bit() | lr.bit()); |
| 1092 // Save the current handler as the next handler. | 1092 // Save the current handler as the next handler. |
| 1093 mov(r7, Operand(ExternalReference(Isolate::k_handler_address))); | 1093 mov(r7, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1094 ldr(r6, MemOperand(r7)); | 1094 ldr(r6, MemOperand(r7)); |
| 1095 ASSERT(StackHandlerConstants::kNextOffset == 0); | 1095 ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 1096 push(r6); | 1096 push(r6); |
| 1097 // Link this handler as the new current one. | 1097 // Link this handler as the new current one. |
| 1098 str(sp, MemOperand(r7)); | 1098 str(sp, MemOperand(r7)); |
| 1099 } | 1099 } |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 | 1102 |
| 1103 void MacroAssembler::PopTryHandler() { | 1103 void MacroAssembler::PopTryHandler() { |
| 1104 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 1104 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); |
| 1105 pop(r1); | 1105 pop(r1); |
| 1106 mov(ip, Operand(ExternalReference(Isolate::k_handler_address))); | 1106 mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1107 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | 1107 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| 1108 str(r1, MemOperand(ip)); | 1108 str(r1, MemOperand(ip)); |
| 1109 } | 1109 } |
| 1110 | 1110 |
| 1111 | 1111 |
| 1112 void MacroAssembler::Throw(Register value) { | 1112 void MacroAssembler::Throw(Register value) { |
| 1113 // r0 is expected to hold the exception. | 1113 // r0 is expected to hold the exception. |
| 1114 if (!value.is(r0)) { | 1114 if (!value.is(r0)) { |
| 1115 mov(r0, value); | 1115 mov(r0, value); |
| 1116 } | 1116 } |
| 1117 | 1117 |
| 1118 // Adjust this code if not the case. | 1118 // Adjust this code if not the case. |
| 1119 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 1119 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
| 1120 | 1120 |
| 1121 // Drop the sp to the top of the handler. | 1121 // Drop the sp to the top of the handler. |
| 1122 mov(r3, Operand(ExternalReference(Isolate::k_handler_address))); | 1122 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1123 ldr(sp, MemOperand(r3)); | 1123 ldr(sp, MemOperand(r3)); |
| 1124 | 1124 |
| 1125 // Restore the next handler and frame pointer, discard handler state. | 1125 // Restore the next handler and frame pointer, discard handler state. |
| 1126 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 1126 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 1127 pop(r2); | 1127 pop(r2); |
| 1128 str(r2, MemOperand(r3)); | 1128 str(r2, MemOperand(r3)); |
| 1129 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 1129 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| 1130 ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state. | 1130 ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state. |
| 1131 | 1131 |
| 1132 // Before returning we restore the context from the frame pointer if | 1132 // Before returning we restore the context from the frame pointer if |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1151 Register value) { | 1151 Register value) { |
| 1152 // Adjust this code if not the case. | 1152 // Adjust this code if not the case. |
| 1153 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 1153 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
| 1154 | 1154 |
| 1155 // r0 is expected to hold the exception. | 1155 // r0 is expected to hold the exception. |
| 1156 if (!value.is(r0)) { | 1156 if (!value.is(r0)) { |
| 1157 mov(r0, value); | 1157 mov(r0, value); |
| 1158 } | 1158 } |
| 1159 | 1159 |
| 1160 // Drop sp to the top stack handler. | 1160 // Drop sp to the top stack handler. |
| 1161 mov(r3, Operand(ExternalReference(Isolate::k_handler_address))); | 1161 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1162 ldr(sp, MemOperand(r3)); | 1162 ldr(sp, MemOperand(r3)); |
| 1163 | 1163 |
| 1164 // Unwind the handlers until the ENTRY handler is found. | 1164 // Unwind the handlers until the ENTRY handler is found. |
| 1165 Label loop, done; | 1165 Label loop, done; |
| 1166 bind(&loop); | 1166 bind(&loop); |
| 1167 // Load the type of the current stack handler. | 1167 // Load the type of the current stack handler. |
| 1168 const int kStateOffset = StackHandlerConstants::kStateOffset; | 1168 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 1169 ldr(r2, MemOperand(sp, kStateOffset)); | 1169 ldr(r2, MemOperand(sp, kStateOffset)); |
| 1170 cmp(r2, Operand(StackHandler::ENTRY)); | 1170 cmp(r2, Operand(StackHandler::ENTRY)); |
| 1171 b(eq, &done); | 1171 b(eq, &done); |
| 1172 // Fetch the next handler in the list. | 1172 // Fetch the next handler in the list. |
| 1173 const int kNextOffset = StackHandlerConstants::kNextOffset; | 1173 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 1174 ldr(sp, MemOperand(sp, kNextOffset)); | 1174 ldr(sp, MemOperand(sp, kNextOffset)); |
| 1175 jmp(&loop); | 1175 jmp(&loop); |
| 1176 bind(&done); | 1176 bind(&done); |
| 1177 | 1177 |
| 1178 // Set the top handler address to next handler past the current ENTRY handler. | 1178 // Set the top handler address to next handler past the current ENTRY handler. |
| 1179 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 1179 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 1180 pop(r2); | 1180 pop(r2); |
| 1181 str(r2, MemOperand(r3)); | 1181 str(r2, MemOperand(r3)); |
| 1182 | 1182 |
| 1183 if (type == OUT_OF_MEMORY) { | 1183 if (type == OUT_OF_MEMORY) { |
| 1184 // Set external caught exception to false. | 1184 // Set external caught exception to false. |
| 1185 ExternalReference external_caught( | 1185 ExternalReference external_caught( |
| 1186 Isolate::k_external_caught_exception_address); | 1186 Isolate::k_external_caught_exception_address, isolate()); |
| 1187 mov(r0, Operand(false, RelocInfo::NONE)); | 1187 mov(r0, Operand(false, RelocInfo::NONE)); |
| 1188 mov(r2, Operand(external_caught)); | 1188 mov(r2, Operand(external_caught)); |
| 1189 str(r0, MemOperand(r2)); | 1189 str(r0, MemOperand(r2)); |
| 1190 | 1190 |
| 1191 // Set pending exception and r0 to out of memory exception. | 1191 // Set pending exception and r0 to out of memory exception. |
| 1192 Failure* out_of_memory = Failure::OutOfMemoryException(); | 1192 Failure* out_of_memory = Failure::OutOfMemoryException(); |
| 1193 mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 1193 mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
| 1194 mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address))); | 1194 mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 1195 isolate()))); |
| 1195 str(r0, MemOperand(r2)); | 1196 str(r0, MemOperand(r2)); |
| 1196 } | 1197 } |
| 1197 | 1198 |
| 1198 // Stack layout at this point. See also StackHandlerConstants. | 1199 // Stack layout at this point. See also StackHandlerConstants. |
| 1199 // sp -> state (ENTRY) | 1200 // sp -> state (ENTRY) |
| 1200 // fp | 1201 // fp |
| 1201 // lr | 1202 // lr |
| 1202 | 1203 |
| 1203 // Discard handler state (r2 is not used) and restore frame pointer. | 1204 // Discard handler state (r2 is not used) and restore frame pointer. |
| 1204 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 1205 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 if ((flags & SIZE_IN_WORDS) != 0) { | 1326 if ((flags & SIZE_IN_WORDS) != 0) { |
| 1326 object_size *= kPointerSize; | 1327 object_size *= kPointerSize; |
| 1327 } | 1328 } |
| 1328 ASSERT_EQ(0, object_size & kObjectAlignmentMask); | 1329 ASSERT_EQ(0, object_size & kObjectAlignmentMask); |
| 1329 | 1330 |
| 1330 // Check relative positions of allocation top and limit addresses. | 1331 // Check relative positions of allocation top and limit addresses. |
| 1331 // The values must be adjacent in memory to allow the use of LDM. | 1332 // The values must be adjacent in memory to allow the use of LDM. |
| 1332 // Also, assert that the registers are numbered such that the values | 1333 // Also, assert that the registers are numbered such that the values |
| 1333 // are loaded in the correct order. | 1334 // are loaded in the correct order. |
| 1334 ExternalReference new_space_allocation_top = | 1335 ExternalReference new_space_allocation_top = |
| 1335 ExternalReference::new_space_allocation_top_address(); | 1336 ExternalReference::new_space_allocation_top_address(isolate()); |
| 1336 ExternalReference new_space_allocation_limit = | 1337 ExternalReference new_space_allocation_limit = |
| 1337 ExternalReference::new_space_allocation_limit_address(); | 1338 ExternalReference::new_space_allocation_limit_address(isolate()); |
| 1338 intptr_t top = | 1339 intptr_t top = |
| 1339 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); | 1340 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); |
| 1340 intptr_t limit = | 1341 intptr_t limit = |
| 1341 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); | 1342 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); |
| 1342 ASSERT((limit - top) == kPointerSize); | 1343 ASSERT((limit - top) == kPointerSize); |
| 1343 ASSERT(result.code() < ip.code()); | 1344 ASSERT(result.code() < ip.code()); |
| 1344 | 1345 |
| 1345 // Set up allocation top address and object size registers. | 1346 // Set up allocation top address and object size registers. |
| 1346 Register topaddr = scratch1; | 1347 Register topaddr = scratch1; |
| 1347 Register obj_size_reg = scratch2; | 1348 Register obj_size_reg = scratch2; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 ASSERT(!scratch1.is(scratch2)); | 1406 ASSERT(!scratch1.is(scratch2)); |
| 1406 ASSERT(!result.is(ip)); | 1407 ASSERT(!result.is(ip)); |
| 1407 ASSERT(!scratch1.is(ip)); | 1408 ASSERT(!scratch1.is(ip)); |
| 1408 ASSERT(!scratch2.is(ip)); | 1409 ASSERT(!scratch2.is(ip)); |
| 1409 | 1410 |
| 1410 // Check relative positions of allocation top and limit addresses. | 1411 // Check relative positions of allocation top and limit addresses. |
| 1411 // The values must be adjacent in memory to allow the use of LDM. | 1412 // The values must be adjacent in memory to allow the use of LDM. |
| 1412 // Also, assert that the registers are numbered such that the values | 1413 // Also, assert that the registers are numbered such that the values |
| 1413 // are loaded in the correct order. | 1414 // are loaded in the correct order. |
| 1414 ExternalReference new_space_allocation_top = | 1415 ExternalReference new_space_allocation_top = |
| 1415 ExternalReference::new_space_allocation_top_address(); | 1416 ExternalReference::new_space_allocation_top_address(isolate()); |
| 1416 ExternalReference new_space_allocation_limit = | 1417 ExternalReference new_space_allocation_limit = |
| 1417 ExternalReference::new_space_allocation_limit_address(); | 1418 ExternalReference::new_space_allocation_limit_address(isolate()); |
| 1418 intptr_t top = | 1419 intptr_t top = |
| 1419 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); | 1420 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); |
| 1420 intptr_t limit = | 1421 intptr_t limit = |
| 1421 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); | 1422 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); |
| 1422 ASSERT((limit - top) == kPointerSize); | 1423 ASSERT((limit - top) == kPointerSize); |
| 1423 ASSERT(result.code() < ip.code()); | 1424 ASSERT(result.code() < ip.code()); |
| 1424 | 1425 |
| 1425 // Set up allocation top address. | 1426 // Set up allocation top address. |
| 1426 Register topaddr = scratch1; | 1427 Register topaddr = scratch1; |
| 1427 mov(topaddr, Operand(new_space_allocation_top)); | 1428 mov(topaddr, Operand(new_space_allocation_top)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 // Tag object if requested. | 1467 // Tag object if requested. |
| 1467 if ((flags & TAG_OBJECT) != 0) { | 1468 if ((flags & TAG_OBJECT) != 0) { |
| 1468 add(result, result, Operand(kHeapObjectTag)); | 1469 add(result, result, Operand(kHeapObjectTag)); |
| 1469 } | 1470 } |
| 1470 } | 1471 } |
| 1471 | 1472 |
| 1472 | 1473 |
| 1473 void MacroAssembler::UndoAllocationInNewSpace(Register object, | 1474 void MacroAssembler::UndoAllocationInNewSpace(Register object, |
| 1474 Register scratch) { | 1475 Register scratch) { |
| 1475 ExternalReference new_space_allocation_top = | 1476 ExternalReference new_space_allocation_top = |
| 1476 ExternalReference::new_space_allocation_top_address(); | 1477 ExternalReference::new_space_allocation_top_address(isolate()); |
| 1477 | 1478 |
| 1478 // Make sure the object has no tag before resetting top. | 1479 // Make sure the object has no tag before resetting top. |
| 1479 and_(object, object, Operand(~kHeapObjectTagMask)); | 1480 and_(object, object, Operand(~kHeapObjectTagMask)); |
| 1480 #ifdef DEBUG | 1481 #ifdef DEBUG |
| 1481 // Check that the object un-allocated is below the current top. | 1482 // Check that the object un-allocated is below the current top. |
| 1482 mov(scratch, Operand(new_space_allocation_top)); | 1483 mov(scratch, Operand(new_space_allocation_top)); |
| 1483 ldr(scratch, MemOperand(scratch)); | 1484 ldr(scratch, MemOperand(scratch)); |
| 1484 cmp(object, scratch); | 1485 cmp(object, scratch); |
| 1485 Check(lt, "Undo allocation of non allocated memory"); | 1486 Check(lt, "Undo allocation of non allocated memory"); |
| 1486 #endif | 1487 #endif |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1768 } | 1769 } |
| 1769 sub(r6, r6, Operand(1)); | 1770 sub(r6, r6, Operand(1)); |
| 1770 str(r6, MemOperand(r7, kLevelOffset)); | 1771 str(r6, MemOperand(r7, kLevelOffset)); |
| 1771 ldr(ip, MemOperand(r7, kLimitOffset)); | 1772 ldr(ip, MemOperand(r7, kLimitOffset)); |
| 1772 cmp(r5, ip); | 1773 cmp(r5, ip); |
| 1773 b(ne, &delete_allocated_handles); | 1774 b(ne, &delete_allocated_handles); |
| 1774 | 1775 |
| 1775 // Check if the function scheduled an exception. | 1776 // Check if the function scheduled an exception. |
| 1776 bind(&leave_exit_frame); | 1777 bind(&leave_exit_frame); |
| 1777 LoadRoot(r4, Heap::kTheHoleValueRootIndex); | 1778 LoadRoot(r4, Heap::kTheHoleValueRootIndex); |
| 1778 mov(ip, Operand(ExternalReference::scheduled_exception_address())); | 1779 mov(ip, Operand(ExternalReference::scheduled_exception_address(isolate()))); |
| 1779 ldr(r5, MemOperand(ip)); | 1780 ldr(r5, MemOperand(ip)); |
| 1780 cmp(r4, r5); | 1781 cmp(r4, r5); |
| 1781 b(ne, &promote_scheduled_exception); | 1782 b(ne, &promote_scheduled_exception); |
| 1782 | 1783 |
| 1783 // LeaveExitFrame expects unwind space to be in a register. | 1784 // LeaveExitFrame expects unwind space to be in a register. |
| 1784 mov(r4, Operand(stack_space)); | 1785 mov(r4, Operand(stack_space)); |
| 1785 LeaveExitFrame(false, r4); | 1786 LeaveExitFrame(false, r4); |
| 1786 mov(pc, lr); | 1787 mov(pc, lr); |
| 1787 | 1788 |
| 1788 bind(&promote_scheduled_exception); | 1789 bind(&promote_scheduled_exception); |
| 1789 MaybeObject* result = TryTailCallExternalReference( | 1790 MaybeObject* result |
| 1790 ExternalReference(Runtime::kPromoteScheduledException), 0, 1); | 1791 = TryTailCallExternalReference( |
| 1792 ExternalReference(Runtime::kPromoteScheduledException, isolate()), |
| 1793 0, |
| 1794 1); |
| 1791 if (result->IsFailure()) { | 1795 if (result->IsFailure()) { |
| 1792 return result; | 1796 return result; |
| 1793 } | 1797 } |
| 1794 | 1798 |
| 1795 // HandleScope limit has changed. Delete allocated extensions. | 1799 // HandleScope limit has changed. Delete allocated extensions. |
| 1796 bind(&delete_allocated_handles); | 1800 bind(&delete_allocated_handles); |
| 1797 str(r5, MemOperand(r7, kLimitOffset)); | 1801 str(r5, MemOperand(r7, kLimitOffset)); |
| 1798 mov(r4, r0); | 1802 mov(r4, r0); |
| 1799 PrepareCallCFunction(0, r5); | 1803 PrepareCallCFunction(0, r5); |
| 1800 CallCFunction(ExternalReference::delete_handle_scope_extensions(), 0); | 1804 CallCFunction( |
| 1805 ExternalReference::delete_handle_scope_extensions(isolate()), 0); |
| 1801 mov(r0, r4); | 1806 mov(r0, r4); |
| 1802 jmp(&leave_exit_frame); | 1807 jmp(&leave_exit_frame); |
| 1803 | 1808 |
| 1804 return result; | 1809 return result; |
| 1805 } | 1810 } |
| 1806 | 1811 |
| 1807 | 1812 |
| 1808 void MacroAssembler::IllegalOperation(int num_arguments) { | 1813 void MacroAssembler::IllegalOperation(int num_arguments) { |
| 1809 if (num_arguments > 0) { | 1814 if (num_arguments > 0) { |
| 1810 add(sp, sp, Operand(num_arguments * kPointerSize)); | 1815 add(sp, sp, Operand(num_arguments * kPointerSize)); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2178 if (f->nargs >= 0 && f->nargs != num_arguments) { | 2183 if (f->nargs >= 0 && f->nargs != num_arguments) { |
| 2179 IllegalOperation(num_arguments); | 2184 IllegalOperation(num_arguments); |
| 2180 return; | 2185 return; |
| 2181 } | 2186 } |
| 2182 | 2187 |
| 2183 // TODO(1236192): Most runtime routines don't need the number of | 2188 // TODO(1236192): Most runtime routines don't need the number of |
| 2184 // arguments passed in because it is constant. At some point we | 2189 // arguments passed in because it is constant. At some point we |
| 2185 // should remove this need and make the runtime routine entry code | 2190 // should remove this need and make the runtime routine entry code |
| 2186 // smarter. | 2191 // smarter. |
| 2187 mov(r0, Operand(num_arguments)); | 2192 mov(r0, Operand(num_arguments)); |
| 2188 mov(r1, Operand(ExternalReference(f))); | 2193 mov(r1, Operand(ExternalReference(f, isolate()))); |
| 2189 CEntryStub stub(1); | 2194 CEntryStub stub(1); |
| 2190 CallStub(&stub); | 2195 CallStub(&stub); |
| 2191 } | 2196 } |
| 2192 | 2197 |
| 2193 | 2198 |
| 2194 void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) { | 2199 void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) { |
| 2195 CallRuntime(Runtime::FunctionForId(fid), num_arguments); | 2200 CallRuntime(Runtime::FunctionForId(fid), num_arguments); |
| 2196 } | 2201 } |
| 2197 | 2202 |
| 2198 | 2203 |
| 2199 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { | 2204 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
| 2200 const Runtime::Function* function = Runtime::FunctionForId(id); | 2205 const Runtime::Function* function = Runtime::FunctionForId(id); |
| 2201 mov(r0, Operand(function->nargs)); | 2206 mov(r0, Operand(function->nargs)); |
| 2202 mov(r1, Operand(ExternalReference(function))); | 2207 mov(r1, Operand(ExternalReference(function, isolate()))); |
| 2203 CEntryStub stub(1); | 2208 CEntryStub stub(1); |
| 2204 stub.SaveDoubles(); | 2209 stub.SaveDoubles(); |
| 2205 CallStub(&stub); | 2210 CallStub(&stub); |
| 2206 } | 2211 } |
| 2207 | 2212 |
| 2208 | 2213 |
| 2209 void MacroAssembler::CallExternalReference(const ExternalReference& ext, | 2214 void MacroAssembler::CallExternalReference(const ExternalReference& ext, |
| 2210 int num_arguments) { | 2215 int num_arguments) { |
| 2211 mov(r0, Operand(num_arguments)); | 2216 mov(r0, Operand(num_arguments)); |
| 2212 mov(r1, Operand(ext)); | 2217 mov(r1, Operand(ext)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2235 // should remove this need and make the runtime routine entry code | 2240 // should remove this need and make the runtime routine entry code |
| 2236 // smarter. | 2241 // smarter. |
| 2237 mov(r0, Operand(num_arguments)); | 2242 mov(r0, Operand(num_arguments)); |
| 2238 return TryJumpToExternalReference(ext); | 2243 return TryJumpToExternalReference(ext); |
| 2239 } | 2244 } |
| 2240 | 2245 |
| 2241 | 2246 |
| 2242 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, | 2247 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
| 2243 int num_arguments, | 2248 int num_arguments, |
| 2244 int result_size) { | 2249 int result_size) { |
| 2245 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); | 2250 TailCallExternalReference(ExternalReference(fid, isolate()), |
| 2251 num_arguments, |
| 2252 result_size); |
| 2246 } | 2253 } |
| 2247 | 2254 |
| 2248 | 2255 |
| 2249 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { | 2256 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { |
| 2250 #if defined(__thumb__) | 2257 #if defined(__thumb__) |
| 2251 // Thumb mode builtin. | 2258 // Thumb mode builtin. |
| 2252 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); | 2259 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); |
| 2253 #endif | 2260 #endif |
| 2254 mov(r1, Operand(builtin)); | 2261 mov(r1, Operand(builtin)); |
| 2255 CEntryStub stub(1); | 2262 CEntryStub stub(1); |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2813 | 2820 |
| 2814 void MacroAssembler::CallCFunction(ExternalReference function, | 2821 void MacroAssembler::CallCFunction(ExternalReference function, |
| 2815 int num_arguments) { | 2822 int num_arguments) { |
| 2816 CallCFunctionHelper(no_reg, function, ip, num_arguments); | 2823 CallCFunctionHelper(no_reg, function, ip, num_arguments); |
| 2817 } | 2824 } |
| 2818 | 2825 |
| 2819 void MacroAssembler::CallCFunction(Register function, | 2826 void MacroAssembler::CallCFunction(Register function, |
| 2820 Register scratch, | 2827 Register scratch, |
| 2821 int num_arguments) { | 2828 int num_arguments) { |
| 2822 CallCFunctionHelper(function, | 2829 CallCFunctionHelper(function, |
| 2823 ExternalReference::the_hole_value_location(), | 2830 ExternalReference::the_hole_value_location(isolate()), |
| 2824 scratch, | 2831 scratch, |
| 2825 num_arguments); | 2832 num_arguments); |
| 2826 } | 2833 } |
| 2827 | 2834 |
| 2828 | 2835 |
| 2829 void MacroAssembler::CallCFunctionHelper(Register function, | 2836 void MacroAssembler::CallCFunctionHelper(Register function, |
| 2830 ExternalReference function_reference, | 2837 ExternalReference function_reference, |
| 2831 Register scratch, | 2838 Register scratch, |
| 2832 int num_arguments) { | 2839 int num_arguments) { |
| 2833 // Push Isolate address as the last argument. | 2840 // Push Isolate address as the last argument. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2936 void CodePatcher::EmitCondition(Condition cond) { | 2943 void CodePatcher::EmitCondition(Condition cond) { |
| 2937 Instr instr = Assembler::instr_at(masm_.pc_); | 2944 Instr instr = Assembler::instr_at(masm_.pc_); |
| 2938 instr = (instr & ~kCondMask) | cond; | 2945 instr = (instr & ~kCondMask) | cond; |
| 2939 masm_.emit(instr); | 2946 masm_.emit(instr); |
| 2940 } | 2947 } |
| 2941 | 2948 |
| 2942 | 2949 |
| 2943 } } // namespace v8::internal | 2950 } } // namespace v8::internal |
| 2944 | 2951 |
| 2945 #endif // V8_TARGET_ARCH_ARM | 2952 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |