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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 void SafeStackTraceFrameIterator::Advance() { | 359 void SafeStackTraceFrameIterator::Advance() { |
360 while (true) { | 360 while (true) { |
361 SafeJavaScriptFrameIterator::Advance(); | 361 SafeJavaScriptFrameIterator::Advance(); |
362 if (done()) return; | 362 if (done()) return; |
363 if (frame()->is_java_script()) return; | 363 if (frame()->is_java_script()) return; |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 | 367 |
368 Code* StackFrame::GetSafepointData(Isolate* isolate, | 368 Code* StackFrame::GetSafepointData(Isolate* isolate, |
369 Address pc, | 369 Address inner_pointer, |
370 SafepointEntry* safepoint_entry, | 370 SafepointEntry* safepoint_entry, |
371 unsigned* stack_slots) { | 371 unsigned* stack_slots) { |
372 PcToCodeCache::PcToCodeCacheEntry* entry = | 372 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry = |
373 isolate->pc_to_code_cache()->GetCacheEntry(pc); | 373 isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer); |
374 if (!entry->safepoint_entry.is_valid()) { | 374 if (!entry->safepoint_entry.is_valid()) { |
375 entry->safepoint_entry = entry->code->GetSafepointEntry(pc); | 375 entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer); |
376 ASSERT(entry->safepoint_entry.is_valid()); | 376 ASSERT(entry->safepoint_entry.is_valid()); |
377 } else { | 377 } else { |
378 ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc))); | 378 ASSERT(entry->safepoint_entry.Equals( |
| 379 entry->code->GetSafepointEntry(inner_pointer))); |
379 } | 380 } |
380 | 381 |
381 // Fill in the results and return the code. | 382 // Fill in the results and return the code. |
382 Code* code = entry->code; | 383 Code* code = entry->code; |
383 *safepoint_entry = entry->safepoint_entry; | 384 *safepoint_entry = entry->safepoint_entry; |
384 *stack_slots = code->stack_slots(); | 385 *stack_slots = code->stack_slots(); |
385 return code; | 386 return code; |
386 } | 387 } |
387 | 388 |
388 | 389 |
389 bool StackFrame::HasHandler() const { | 390 bool StackFrame::HasHandler() const { |
390 StackHandlerIterator it(this, top_handler()); | 391 StackHandlerIterator it(this, top_handler()); |
391 return !it.done(); | 392 return !it.done(); |
392 } | 393 } |
393 | 394 |
394 | 395 |
| 396 #ifdef DEBUG |
| 397 static bool GcSafeCodeContains(HeapObject* object, Address addr); |
| 398 #endif |
| 399 |
| 400 |
395 void StackFrame::IteratePc(ObjectVisitor* v, | 401 void StackFrame::IteratePc(ObjectVisitor* v, |
396 Address* pc_address, | 402 Address* pc_address, |
397 Code* holder) { | 403 Code* holder) { |
398 Address pc = *pc_address; | 404 Address pc = *pc_address; |
399 ASSERT(holder->contains(pc)); | 405 ASSERT(GcSafeCodeContains(holder, pc)); |
400 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); | 406 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); |
401 Object* code = holder; | 407 Object* code = holder; |
402 v->VisitPointer(&code); | 408 v->VisitPointer(&code); |
403 if (code != holder) { | 409 if (code != holder) { |
404 holder = reinterpret_cast<Code*>(code); | 410 holder = reinterpret_cast<Code*>(code); |
405 pc = holder->instruction_start() + pc_offset; | 411 pc = holder->instruction_start() + pc_offset; |
406 *pc_address = pc; | 412 *pc_address = pc; |
407 } | 413 } |
408 } | 414 } |
409 | 415 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 int* deopt_index) { | 818 int* deopt_index) { |
813 ASSERT(is_optimized()); | 819 ASSERT(is_optimized()); |
814 | 820 |
815 JSFunction* opt_function = JSFunction::cast(function()); | 821 JSFunction* opt_function = JSFunction::cast(function()); |
816 Code* code = opt_function->code(); | 822 Code* code = opt_function->code(); |
817 | 823 |
818 // The code object may have been replaced by lazy deoptimization. Fall | 824 // The code object may have been replaced by lazy deoptimization. Fall |
819 // back to a slow search in this case to find the original optimized | 825 // back to a slow search in this case to find the original optimized |
820 // code object. | 826 // code object. |
821 if (!code->contains(pc())) { | 827 if (!code->contains(pc())) { |
822 code = isolate()->pc_to_code_cache()->GcSafeFindCodeForPc(pc()); | 828 code = isolate()->inner_pointer_to_code_cache()-> |
| 829 GcSafeFindCodeForInnerPointer(pc()); |
823 } | 830 } |
824 ASSERT(code != NULL); | 831 ASSERT(code != NULL); |
825 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); | 832 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); |
826 | 833 |
827 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); | 834 SafepointEntry safepoint_entry = code->GetSafepointEntry(pc()); |
828 *deopt_index = safepoint_entry.deoptimization_index(); | 835 *deopt_index = safepoint_entry.deoptimization_index(); |
829 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); | 836 ASSERT(*deopt_index != Safepoint::kNoDeoptimizationIndex); |
830 | 837 |
831 return DeoptimizationInputData::cast(code->deoptimization_data()); | 838 return DeoptimizationInputData::cast(code->deoptimization_data()); |
832 } | 839 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 JSFunction::cast(data->LiteralArray()->get(function_id)); | 881 JSFunction::cast(data->LiteralArray()->get(function_id)); |
875 functions->Add(function); | 882 functions->Add(function); |
876 } else { | 883 } else { |
877 // Skip over operands to advance to the next opcode. | 884 // Skip over operands to advance to the next opcode. |
878 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 885 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
879 } | 886 } |
880 } | 887 } |
881 } | 888 } |
882 | 889 |
883 | 890 |
| 891 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { |
| 892 return Smi::cast(GetExpression(0))->value(); |
| 893 } |
| 894 |
| 895 |
884 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 896 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
885 return fp() + StandardFrameConstants::kCallerSPOffset; | 897 return fp() + StandardFrameConstants::kCallerSPOffset; |
886 } | 898 } |
887 | 899 |
888 | 900 |
889 Address InternalFrame::GetCallerStackPointer() const { | 901 Address InternalFrame::GetCallerStackPointer() const { |
890 // Internal frames have no arguments. The stack pointer of the | 902 // Internal frames have no arguments. The stack pointer of the |
891 // caller is at a fixed offset from the frame pointer. | 903 // caller is at a fixed offset from the frame pointer. |
892 return fp() + StandardFrameConstants::kCallerSPOffset; | 904 return fp() + StandardFrameConstants::kCallerSPOffset; |
893 } | 905 } |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 iterator_.Advance(); | 1160 iterator_.Advance(); |
1149 } | 1161 } |
1150 UNREACHABLE(); | 1162 UNREACHABLE(); |
1151 return NULL; | 1163 return NULL; |
1152 } | 1164 } |
1153 | 1165 |
1154 | 1166 |
1155 // ------------------------------------------------------------------------- | 1167 // ------------------------------------------------------------------------- |
1156 | 1168 |
1157 | 1169 |
1158 Code* PcToCodeCache::GcSafeCastToCode(HeapObject* object, Address pc) { | 1170 static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) { |
| 1171 MapWord map_word = object->map_word(); |
| 1172 return map_word.IsForwardingAddress() ? |
| 1173 map_word.ToForwardingAddress()->map() : map_word.ToMap(); |
| 1174 } |
| 1175 |
| 1176 |
| 1177 static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) { |
| 1178 return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object)); |
| 1179 } |
| 1180 |
| 1181 |
| 1182 #ifdef DEBUG |
| 1183 static bool GcSafeCodeContains(HeapObject* code, Address addr) { |
| 1184 Map* map = GcSafeMapOfCodeSpaceObject(code); |
| 1185 ASSERT(map == code->GetHeap()->code_map()); |
| 1186 Address start = code->address(); |
| 1187 Address end = code->address() + code->SizeFromMap(map); |
| 1188 return start <= addr && addr < end; |
| 1189 } |
| 1190 #endif |
| 1191 |
| 1192 |
| 1193 Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object, |
| 1194 Address inner_pointer) { |
1159 Code* code = reinterpret_cast<Code*>(object); | 1195 Code* code = reinterpret_cast<Code*>(object); |
1160 ASSERT(code != NULL && code->contains(pc)); | 1196 ASSERT(code != NULL && GcSafeCodeContains(code, inner_pointer)); |
1161 return code; | 1197 return code; |
1162 } | 1198 } |
1163 | 1199 |
1164 | 1200 |
1165 Code* PcToCodeCache::GcSafeFindCodeForPc(Address pc) { | 1201 Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer( |
| 1202 Address inner_pointer) { |
1166 Heap* heap = isolate_->heap(); | 1203 Heap* heap = isolate_->heap(); |
1167 // Check if the pc points into a large object chunk. | 1204 // Check if the inner pointer points into a large object chunk. |
1168 LargeObjectChunk* chunk = heap->lo_space()->FindChunkContainingPc(pc); | 1205 LargePage* large_page = heap->lo_space()->FindPageContainingPc(inner_pointer); |
1169 if (chunk != NULL) return GcSafeCastToCode(chunk->GetObject(), pc); | 1206 if (large_page != NULL) { |
| 1207 return GcSafeCastToCode(large_page->GetObject(), inner_pointer); |
| 1208 } |
1170 | 1209 |
1171 // Iterate through the 8K page until we reach the end or find an | 1210 // Iterate through the page until we reach the end or find an object starting |
1172 // object starting after the pc. | 1211 // after the inner pointer. |
1173 Page* page = Page::FromAddress(pc); | 1212 Page* page = Page::FromAddress(inner_pointer); |
1174 HeapObjectIterator iterator(page, heap->GcSafeSizeOfOldObjectFunction()); | 1213 |
1175 HeapObject* previous = NULL; | 1214 Address addr = page->skip_list()->StartFor(inner_pointer); |
| 1215 |
| 1216 Address top = heap->code_space()->top(); |
| 1217 Address limit = heap->code_space()->limit(); |
| 1218 |
1176 while (true) { | 1219 while (true) { |
1177 HeapObject* next = iterator.next(); | 1220 if (addr == top && addr != limit) { |
1178 if (next == NULL || next->address() >= pc) { | 1221 addr = limit; |
1179 return GcSafeCastToCode(previous, pc); | 1222 continue; |
1180 } | 1223 } |
1181 previous = next; | 1224 |
| 1225 HeapObject* obj = HeapObject::FromAddress(addr); |
| 1226 int obj_size = GcSafeSizeOfCodeSpaceObject(obj); |
| 1227 Address next_addr = addr + obj_size; |
| 1228 if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer); |
| 1229 addr = next_addr; |
1182 } | 1230 } |
1183 } | 1231 } |
1184 | 1232 |
1185 | 1233 |
1186 PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) { | 1234 InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* |
| 1235 InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) { |
1187 isolate_->counters()->pc_to_code()->Increment(); | 1236 isolate_->counters()->pc_to_code()->Increment(); |
1188 ASSERT(IsPowerOf2(kPcToCodeCacheSize)); | 1237 ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize)); |
1189 uint32_t hash = ComputeIntegerHash( | 1238 uint32_t hash = ComputeIntegerHash( |
1190 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc))); | 1239 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer))); |
1191 uint32_t index = hash & (kPcToCodeCacheSize - 1); | 1240 uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1); |
1192 PcToCodeCacheEntry* entry = cache(index); | 1241 InnerPointerToCodeCacheEntry* entry = cache(index); |
1193 if (entry->pc == pc) { | 1242 if (entry->inner_pointer == inner_pointer) { |
1194 isolate_->counters()->pc_to_code_cached()->Increment(); | 1243 isolate_->counters()->pc_to_code_cached()->Increment(); |
1195 ASSERT(entry->code == GcSafeFindCodeForPc(pc)); | 1244 ASSERT(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer)); |
1196 } else { | 1245 } else { |
1197 // Because this code may be interrupted by a profiling signal that | 1246 // Because this code may be interrupted by a profiling signal that |
1198 // also queries the cache, we cannot update pc before the code has | 1247 // also queries the cache, we cannot update inner_pointer before the code |
1199 // been set. Otherwise, we risk trying to use a cache entry before | 1248 // has been set. Otherwise, we risk trying to use a cache entry before |
1200 // the code has been computed. | 1249 // the code has been computed. |
1201 entry->code = GcSafeFindCodeForPc(pc); | 1250 entry->code = GcSafeFindCodeForInnerPointer(inner_pointer); |
1202 entry->safepoint_entry.Reset(); | 1251 entry->safepoint_entry.Reset(); |
1203 entry->pc = pc; | 1252 entry->inner_pointer = inner_pointer; |
1204 } | 1253 } |
1205 return entry; | 1254 return entry; |
1206 } | 1255 } |
1207 | 1256 |
1208 | 1257 |
1209 // ------------------------------------------------------------------------- | 1258 // ------------------------------------------------------------------------- |
1210 | 1259 |
1211 int NumRegs(RegList reglist) { | 1260 int NumRegs(RegList reglist) { |
1212 int n = 0; | 1261 int n = 0; |
1213 while (reglist != 0) { | 1262 while (reglist != 0) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 ZoneList<StackFrame*> list(10); | 1319 ZoneList<StackFrame*> list(10); |
1271 for (StackFrameIterator it; !it.done(); it.Advance()) { | 1320 for (StackFrameIterator it; !it.done(); it.Advance()) { |
1272 StackFrame* frame = AllocateFrameCopy(it.frame()); | 1321 StackFrame* frame = AllocateFrameCopy(it.frame()); |
1273 list.Add(frame); | 1322 list.Add(frame); |
1274 } | 1323 } |
1275 return list.ToVector(); | 1324 return list.ToVector(); |
1276 } | 1325 } |
1277 | 1326 |
1278 | 1327 |
1279 } } // namespace v8::internal | 1328 } } // namespace v8::internal |
OLD | NEW |