OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 Deoptimizer::HandleWeakDeoptimizedCode); | 1187 Deoptimizer::HandleWeakDeoptimizedCode); |
1188 } | 1188 } |
1189 | 1189 |
1190 | 1190 |
1191 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { | 1191 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { |
1192 GlobalHandles* global_handles = Isolate::Current()->global_handles(); | 1192 GlobalHandles* global_handles = Isolate::Current()->global_handles(); |
1193 global_handles->Destroy(reinterpret_cast<Object**>(code_.location())); | 1193 global_handles->Destroy(reinterpret_cast<Object**>(code_.location())); |
1194 } | 1194 } |
1195 | 1195 |
1196 | 1196 |
| 1197 // We can't intermix stack decoding and allocations because |
| 1198 // deoptimization infrastracture is not GC safe. |
| 1199 // Thus we build a temporary structure in malloced space. |
| 1200 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, |
| 1201 DeoptimizationInputData* data, |
| 1202 JavaScriptFrame* frame) { |
| 1203 Translation::Opcode opcode = |
| 1204 static_cast<Translation::Opcode>(iterator->Next()); |
| 1205 |
| 1206 switch (opcode) { |
| 1207 case Translation::BEGIN: |
| 1208 case Translation::FRAME: |
| 1209 // Peeled off before getting here. |
| 1210 break; |
| 1211 |
| 1212 case Translation::ARGUMENTS_OBJECT: |
| 1213 // This can be only emitted for local slots not for argument slots. |
| 1214 break; |
| 1215 |
| 1216 case Translation::REGISTER: |
| 1217 case Translation::INT32_REGISTER: |
| 1218 case Translation::DOUBLE_REGISTER: |
| 1219 case Translation::DUPLICATE: |
| 1220 // We are at safepoint which corresponds to call. All registers are |
| 1221 // saved by caller so there would be no live registers at this |
| 1222 // point. Thus these translation commands should not be used. |
| 1223 break; |
| 1224 |
| 1225 case Translation::STACK_SLOT: { |
| 1226 int slot_index = iterator->Next(); |
| 1227 Address slot_addr = SlotAddress(frame, slot_index); |
| 1228 return SlotRef(slot_addr, SlotRef::TAGGED); |
| 1229 } |
| 1230 |
| 1231 case Translation::INT32_STACK_SLOT: { |
| 1232 int slot_index = iterator->Next(); |
| 1233 Address slot_addr = SlotAddress(frame, slot_index); |
| 1234 return SlotRef(slot_addr, SlotRef::INT32); |
| 1235 } |
| 1236 |
| 1237 case Translation::DOUBLE_STACK_SLOT: { |
| 1238 int slot_index = iterator->Next(); |
| 1239 Address slot_addr = SlotAddress(frame, slot_index); |
| 1240 return SlotRef(slot_addr, SlotRef::DOUBLE); |
| 1241 } |
| 1242 |
| 1243 case Translation::LITERAL: { |
| 1244 int literal_index = iterator->Next(); |
| 1245 return SlotRef(data->LiteralArray()->get(literal_index)); |
| 1246 } |
| 1247 } |
| 1248 |
| 1249 UNREACHABLE(); |
| 1250 return SlotRef(); |
| 1251 } |
| 1252 |
| 1253 |
| 1254 void SlotRef::ComputeSlotMappingForArguments(JavaScriptFrame* frame, |
| 1255 int inlined_frame_index, |
| 1256 Vector<SlotRef>* args_slots) { |
| 1257 AssertNoAllocation no_gc; |
| 1258 int deopt_index = AstNode::kNoNumber; |
| 1259 DeoptimizationInputData* data = |
| 1260 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); |
| 1261 TranslationIterator it(data->TranslationByteArray(), |
| 1262 data->TranslationIndex(deopt_index)->value()); |
| 1263 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
| 1264 ASSERT(opcode == Translation::BEGIN); |
| 1265 int frame_count = it.Next(); |
| 1266 USE(frame_count); |
| 1267 ASSERT(frame_count > inlined_frame_index); |
| 1268 int frames_to_skip = inlined_frame_index; |
| 1269 while (true) { |
| 1270 opcode = static_cast<Translation::Opcode>(it.Next()); |
| 1271 // Skip over operands to advance to the next opcode. |
| 1272 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 1273 if (opcode == Translation::FRAME) { |
| 1274 if (frames_to_skip == 0) { |
| 1275 // We reached the frame corresponding to the inlined function |
| 1276 // in question. Process the translation commands for the |
| 1277 // arguments. |
| 1278 // |
| 1279 // Skip the translation command for the receiver. |
| 1280 it.Skip(Translation::NumberOfOperandsFor( |
| 1281 static_cast<Translation::Opcode>(it.Next()))); |
| 1282 // Compute slots for arguments. |
| 1283 for (int i = 0; i < args_slots->length(); ++i) { |
| 1284 (*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame); |
| 1285 } |
| 1286 return; |
| 1287 } |
| 1288 frames_to_skip--; |
| 1289 } |
| 1290 } |
| 1291 |
| 1292 UNREACHABLE(); |
| 1293 } |
| 1294 |
| 1295 |
1197 } } // namespace v8::internal | 1296 } } // namespace v8::internal |
OLD | NEW |