Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1141)

Side by Side Diff: src/debug/debug.cc

Issue 1723803004: [interpreter, debugger] replace bytecode on-stack for debugging. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/ignition/debug-break-on-stack.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 public: 1233 public:
1234 explicit RedirectActiveFunctions(SharedFunctionInfo* shared) 1234 explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
1235 : shared_(shared) { 1235 : shared_(shared) {
1236 DCHECK(shared->HasDebugCode()); 1236 DCHECK(shared->HasDebugCode());
1237 } 1237 }
1238 1238
1239 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1239 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1240 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1240 for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1241 JavaScriptFrame* frame = it.frame(); 1241 JavaScriptFrame* frame = it.frame();
1242 JSFunction* function = frame->function(); 1242 JSFunction* function = frame->function();
1243 if (frame->is_interpreted()) {
1244 // TODO(yangguo): replace dispatch table for activated frames.
1245 continue;
1246 }
1247 if (frame->is_optimized()) continue; 1243 if (frame->is_optimized()) continue;
1248 if (!function->Inlines(shared_)) continue; 1244 if (!function->Inlines(shared_)) continue;
1249 1245
1246 if (frame->is_interpreted()) {
1247 InterpretedFrame* interpreted_frame =
1248 reinterpret_cast<InterpretedFrame*>(frame);
1249 BytecodeArray* debug_copy =
1250 shared_->GetDebugInfo()->abstract_code()->GetBytecodeArray();
1251 interpreted_frame->PatchBytecodeArray(debug_copy);
1252 continue;
1253 }
1254
1250 Code* frame_code = frame->LookupCode(); 1255 Code* frame_code = frame->LookupCode();
1251 DCHECK(frame_code->kind() == Code::FUNCTION); 1256 DCHECK(frame_code->kind() == Code::FUNCTION);
1252 if (frame_code->has_debug_break_slots()) continue; 1257 if (frame_code->has_debug_break_slots()) continue;
1253 1258
1254 Code* new_code = function->shared()->code(); 1259 Code* new_code = function->shared()->code();
1255 Address old_pc = frame->pc(); 1260 Address old_pc = frame->pc();
1256 Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc); 1261 Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
1257 1262
1258 if (FLAG_trace_deopt) { 1263 if (FLAG_trace_deopt) {
1259 PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR 1264 PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 while (SharedFunctionInfo* shared = iterator.Next()) { 1302 while (SharedFunctionInfo* shared = iterator.Next()) {
1298 if (!shared->OptimizedCodeMapIsCleared()) { 1303 if (!shared->OptimizedCodeMapIsCleared()) {
1299 shared->ClearOptimizedCodeMap(); 1304 shared->ClearOptimizedCodeMap();
1300 } 1305 }
1301 } 1306 }
1302 } 1307 }
1303 1308
1304 // Make sure we abort incremental marking. 1309 // Make sure we abort incremental marking.
1305 isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask, 1310 isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
1306 "prepare for break points"); 1311 "prepare for break points");
1312 bool is_interpreted = shared->HasBytecodeArray();
1307 1313
1308 { 1314 {
1315 // TODO(yangguo): with bytecode, we still walk the heap to find all
1316 // optimized code for the function to deoptimize. We can probably be
1317 // smarter here and avoid the heap walk.
1309 HeapIterator iterator(isolate_->heap()); 1318 HeapIterator iterator(isolate_->heap());
1310 HeapObject* obj; 1319 HeapObject* obj;
1311 bool include_generators = shared->is_generator(); 1320 bool include_generators = !is_interpreted && shared->is_generator();
1312 1321
1313 while ((obj = iterator.next())) { 1322 while ((obj = iterator.next())) {
1314 if (obj->IsJSFunction()) { 1323 if (obj->IsJSFunction()) {
1315 JSFunction* function = JSFunction::cast(obj); 1324 JSFunction* function = JSFunction::cast(obj);
1316 if (!function->Inlines(*shared)) continue; 1325 if (!function->Inlines(*shared)) continue;
1317 if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) { 1326 if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
1318 Deoptimizer::DeoptimizeFunction(function); 1327 Deoptimizer::DeoptimizeFunction(function);
1319 } 1328 }
1329 if (is_interpreted) continue;
1320 if (function->shared() == *shared) functions.Add(handle(function)); 1330 if (function->shared() == *shared) functions.Add(handle(function));
1321 } else if (include_generators && obj->IsJSGeneratorObject()) { 1331 } else if (include_generators && obj->IsJSGeneratorObject()) {
1322 JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj); 1332 JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj);
1323 if (!generator_obj->is_suspended()) continue; 1333 if (!generator_obj->is_suspended()) continue;
1324 JSFunction* function = generator_obj->function(); 1334 JSFunction* function = generator_obj->function();
1325 if (!function->Inlines(*shared)) continue; 1335 if (!function->Inlines(*shared)) continue;
1326 int pc_offset = generator_obj->continuation(); 1336 int pc_offset = generator_obj->continuation();
1327 int index = 1337 int index =
1328 ComputeContinuationIndexFromPcOffset(function->code(), pc_offset); 1338 ComputeContinuationIndexFromPcOffset(function->code(), pc_offset);
1329 generator_obj->set_continuation(index); 1339 generator_obj->set_continuation(index);
1330 suspended_generators.Add(handle(generator_obj)); 1340 suspended_generators.Add(handle(generator_obj));
1331 } 1341 }
1332 } 1342 }
1333 } 1343 }
1334 1344
1335 if (!shared->HasDebugCode()) { 1345 // We do not need to replace code to debug bytecode.
1346 DCHECK(!is_interpreted || functions.length() == 0);
1347 DCHECK(!is_interpreted || suspended_generators.length() == 0);
1348
1349 // We do not need to recompile to debug bytecode.
1350 if (!is_interpreted && !shared->HasDebugCode()) {
1336 DCHECK(functions.length() > 0); 1351 DCHECK(functions.length() > 0);
1337 if (!Compiler::CompileDebugCode(functions.first())) return false; 1352 if (!Compiler::CompileDebugCode(functions.first())) return false;
1338 } 1353 }
1339 1354
1340 for (Handle<JSFunction> const function : functions) { 1355 for (Handle<JSFunction> const function : functions) {
1341 function->ReplaceCode(shared->code()); 1356 function->ReplaceCode(shared->code());
1342 } 1357 }
1343 1358
1344 for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) { 1359 for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) {
1345 int index = generator_obj->continuation(); 1360 int index = generator_obj->continuation();
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 1511
1497 // Return if we already have the debug info for shared. 1512 // Return if we already have the debug info for shared.
1498 if (shared->HasDebugInfo()) return true; 1513 if (shared->HasDebugInfo()) return true;
1499 1514
1500 if (function.is_null()) { 1515 if (function.is_null()) {
1501 DCHECK(shared->HasDebugCode()); 1516 DCHECK(shared->HasDebugCode());
1502 } else if (!Compiler::Compile(function, CLEAR_EXCEPTION)) { 1517 } else if (!Compiler::Compile(function, CLEAR_EXCEPTION)) {
1503 return false; 1518 return false;
1504 } 1519 }
1505 1520
1506 if (!PrepareFunctionForBreakPoints(shared)) return false; 1521 if (shared->HasBytecodeArray()) {
1507 1522 // To prepare bytecode for debugging, we already need to have the debug
1508 CreateDebugInfo(shared); 1523 // info (containing the debug copy) upfront, but since we do not recompile,
1509 1524 // preparing for break points cannot fail.
1525 CreateDebugInfo(shared);
1526 CHECK(PrepareFunctionForBreakPoints(shared));
1527 } else {
1528 if (!PrepareFunctionForBreakPoints(shared)) return false;
1529 CreateDebugInfo(shared);
1530 }
1510 return true; 1531 return true;
1511 } 1532 }
1512 1533
1513 1534
1514 void Debug::CreateDebugInfo(Handle<SharedFunctionInfo> shared) { 1535 void Debug::CreateDebugInfo(Handle<SharedFunctionInfo> shared) {
1515 // Create the debug info object. 1536 // Create the debug info object.
1516 DCHECK(shared->HasDebugCode()); 1537 DCHECK(shared->HasDebugCode());
1517 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared); 1538 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
1518 1539
1519 // Add debug info to the list. 1540 // Add debug info to the list.
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 } 2616 }
2596 2617
2597 2618
2598 void LockingCommandMessageQueue::Clear() { 2619 void LockingCommandMessageQueue::Clear() {
2599 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2620 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2600 queue_.Clear(); 2621 queue_.Clear();
2601 } 2622 }
2602 2623
2603 } // namespace internal 2624 } // namespace internal
2604 } // namespace v8 2625 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/ignition/debug-break-on-stack.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698