OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/assert-scope.h" | 6 #include "src/assert-scope.h" |
7 #include "src/compiler/wasm-compiler.h" | 7 #include "src/compiler/wasm-compiler.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 std::unique_ptr<wasm::InterpretedFrame> GetInterpretedFrame( | 266 std::unique_ptr<wasm::InterpretedFrame> GetInterpretedFrame( |
267 Address frame_pointer, int idx) { | 267 Address frame_pointer, int idx) { |
268 // TODO(clemensh): Use frame_pointer. | 268 // TODO(clemensh): Use frame_pointer. |
269 USE(frame_pointer); | 269 USE(frame_pointer); |
270 | 270 |
271 DCHECK_EQ(1, interpreter()->GetThreadCount()); | 271 DCHECK_EQ(1, interpreter()->GetThreadCount()); |
272 WasmInterpreter::Thread* thread = interpreter()->GetThread(0); | 272 WasmInterpreter::Thread* thread = interpreter()->GetThread(0); |
273 return std::unique_ptr<wasm::InterpretedFrame>( | 273 return std::unique_ptr<wasm::InterpretedFrame>( |
274 new wasm::InterpretedFrame(thread->GetMutableFrame(idx))); | 274 new wasm::InterpretedFrame(thread->GetMutableFrame(idx))); |
275 } | 275 } |
| 276 |
| 277 uint64_t NumInterpretedCalls() { |
| 278 DCHECK_EQ(1, interpreter()->GetThreadCount()); |
| 279 return interpreter()->GetThread(0)->NumInterpretedCalls(); |
| 280 } |
276 }; | 281 }; |
277 | 282 |
278 InterpreterHandle* GetOrCreateInterpreterHandle( | 283 InterpreterHandle* GetOrCreateInterpreterHandle( |
279 Isolate* isolate, Handle<WasmDebugInfo> debug_info) { | 284 Isolate* isolate, Handle<WasmDebugInfo> debug_info) { |
280 Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandle), | 285 Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandle), |
281 isolate); | 286 isolate); |
282 if (handle->IsUndefined(isolate)) { | 287 if (handle->IsUndefined(isolate)) { |
283 InterpreterHandle* cpp_handle = new InterpreterHandle(isolate, *debug_info); | 288 InterpreterHandle* cpp_handle = new InterpreterHandle(isolate, *debug_info); |
284 handle = Managed<InterpreterHandle>::New(isolate, cpp_handle); | 289 handle = Managed<InterpreterHandle>::New(isolate, cpp_handle); |
285 debug_info->set(WasmDebugInfo::kInterpreterHandle, *handle); | 290 debug_info->set(WasmDebugInfo::kInterpreterHandle, *handle); |
286 } | 291 } |
287 | 292 |
288 return Handle<Managed<InterpreterHandle>>::cast(handle)->get(); | 293 return Handle<Managed<InterpreterHandle>>::cast(handle)->get(); |
289 } | 294 } |
290 | 295 |
291 InterpreterHandle* GetInterpreterHandle(WasmDebugInfo* debug_info) { | 296 InterpreterHandle* GetInterpreterHandle(WasmDebugInfo* debug_info) { |
292 Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandle); | 297 Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandle); |
293 DCHECK(!handle_obj->IsUndefined(debug_info->GetIsolate())); | 298 DCHECK(!handle_obj->IsUndefined(debug_info->GetIsolate())); |
294 return Managed<InterpreterHandle>::cast(handle_obj)->get(); | 299 return Managed<InterpreterHandle>::cast(handle_obj)->get(); |
295 } | 300 } |
296 | 301 |
| 302 InterpreterHandle* GetInterpreterHandleOrNull(WasmDebugInfo* debug_info) { |
| 303 Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandle); |
| 304 if (handle_obj->IsUndefined(debug_info->GetIsolate())) return nullptr; |
| 305 return Managed<InterpreterHandle>::cast(handle_obj)->get(); |
| 306 } |
| 307 |
297 int GetNumFunctions(WasmInstanceObject* instance) { | 308 int GetNumFunctions(WasmInstanceObject* instance) { |
298 size_t num_functions = | 309 size_t num_functions = |
299 instance->compiled_module()->module()->functions.size(); | 310 instance->compiled_module()->module()->functions.size(); |
300 DCHECK_GE(kMaxInt, num_functions); | 311 DCHECK_GE(kMaxInt, num_functions); |
301 return static_cast<int>(num_functions); | 312 return static_cast<int>(num_functions); |
302 } | 313 } |
303 | 314 |
304 Handle<FixedArray> GetOrCreateInterpretedFunctions( | 315 Handle<FixedArray> GetOrCreateInterpretedFunctions( |
305 Isolate* isolate, Handle<WasmDebugInfo> debug_info) { | 316 Isolate* isolate, Handle<WasmDebugInfo> debug_info) { |
306 Handle<Object> obj(debug_info->get(WasmDebugInfo::kInterpretedFunctions), | 317 Handle<Object> obj(debug_info->get(WasmDebugInfo::kInterpretedFunctions), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 FixedArray* weak_exported_functions = | 349 FixedArray* weak_exported_functions = |
339 instance->compiled_module()->ptr_to_weak_exported_functions(); | 350 instance->compiled_module()->ptr_to_weak_exported_functions(); |
340 for (int i = 0, e = weak_exported_functions->length(); i != e; ++i) { | 351 for (int i = 0, e = weak_exported_functions->length(); i != e; ++i) { |
341 WeakCell* weak_function = WeakCell::cast(weak_exported_functions->get(i)); | 352 WeakCell* weak_function = WeakCell::cast(weak_exported_functions->get(i)); |
342 if (weak_function->cleared()) continue; | 353 if (weak_function->cleared()) continue; |
343 Code* code = JSFunction::cast(weak_function->value())->code(); | 354 Code* code = JSFunction::cast(weak_function->value())->code(); |
344 RedirectCallsitesInCode(code, old_target, new_target); | 355 RedirectCallsitesInCode(code, old_target, new_target); |
345 } | 356 } |
346 } | 357 } |
347 | 358 |
348 void EnsureRedirectToInterpreter(Isolate* isolate, | |
349 Handle<WasmDebugInfo> debug_info, | |
350 int func_index) { | |
351 Handle<FixedArray> interpreted_functions = | |
352 GetOrCreateInterpretedFunctions(isolate, debug_info); | |
353 if (!interpreted_functions->get(func_index)->IsUndefined(isolate)) return; | |
354 | |
355 Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate); | |
356 Handle<Code> new_code = compiler::CompileWasmInterpreterEntry( | |
357 isolate, func_index, | |
358 instance->compiled_module()->module()->functions[func_index].sig, | |
359 instance); | |
360 | |
361 Handle<FixedArray> code_table = instance->compiled_module()->code_table(); | |
362 Handle<Code> old_code(Code::cast(code_table->get(func_index)), isolate); | |
363 interpreted_functions->set(func_index, *new_code); | |
364 | |
365 RedirectCallsitesInInstance(isolate, *instance, *old_code, *new_code); | |
366 } | |
367 | |
368 } // namespace | 359 } // namespace |
369 | 360 |
370 Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) { | 361 Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) { |
371 Isolate* isolate = instance->GetIsolate(); | 362 Isolate* isolate = instance->GetIsolate(); |
372 Factory* factory = isolate->factory(); | 363 Factory* factory = isolate->factory(); |
373 Handle<FixedArray> arr = factory->NewFixedArray(kFieldCount, TENURED); | 364 Handle<FixedArray> arr = factory->NewFixedArray(kFieldCount, TENURED); |
374 arr->set(kInstance, *instance); | 365 arr->set(kInstance, *instance); |
375 return Handle<WasmDebugInfo>::cast(arr); | 366 return Handle<WasmDebugInfo>::cast(arr); |
376 } | 367 } |
377 | 368 |
(...skipping 15 matching lines...) Expand all Loading... |
393 } | 384 } |
394 | 385 |
395 WasmInstanceObject* WasmDebugInfo::wasm_instance() { | 386 WasmInstanceObject* WasmDebugInfo::wasm_instance() { |
396 return WasmInstanceObject::cast(get(kInstance)); | 387 return WasmInstanceObject::cast(get(kInstance)); |
397 } | 388 } |
398 | 389 |
399 void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info, | 390 void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info, |
400 int func_index, int offset) { | 391 int func_index, int offset) { |
401 Isolate* isolate = debug_info->GetIsolate(); | 392 Isolate* isolate = debug_info->GetIsolate(); |
402 InterpreterHandle* handle = GetOrCreateInterpreterHandle(isolate, debug_info); | 393 InterpreterHandle* handle = GetOrCreateInterpreterHandle(isolate, debug_info); |
403 WasmInterpreter* interpreter = handle->interpreter(); | 394 RedirectToInterpreter(debug_info, func_index); |
| 395 const WasmFunction* func = &handle->module()->functions[func_index]; |
| 396 handle->interpreter()->SetBreakpoint(func, offset, true); |
| 397 } |
| 398 |
| 399 void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info, |
| 400 int func_index) { |
| 401 Isolate* isolate = debug_info->GetIsolate(); |
404 DCHECK_LE(0, func_index); | 402 DCHECK_LE(0, func_index); |
405 DCHECK_GT(handle->module()->functions.size(), func_index); | 403 DCHECK_GT(debug_info->wasm_instance()->module()->functions.size(), |
406 const WasmFunction* func = &handle->module()->functions[func_index]; | 404 func_index); |
407 interpreter->SetBreakpoint(func, offset, true); | 405 Handle<FixedArray> interpreted_functions = |
408 EnsureRedirectToInterpreter(isolate, debug_info, func_index); | 406 GetOrCreateInterpretedFunctions(isolate, debug_info); |
| 407 if (!interpreted_functions->get(func_index)->IsUndefined(isolate)) return; |
| 408 |
| 409 // Ensure that the interpreter is instantiated. |
| 410 GetOrCreateInterpreterHandle(isolate, debug_info); |
| 411 Handle<WasmInstanceObject> instance(debug_info->wasm_instance(), isolate); |
| 412 Handle<Code> new_code = compiler::CompileWasmInterpreterEntry( |
| 413 isolate, func_index, |
| 414 instance->compiled_module()->module()->functions[func_index].sig, |
| 415 instance); |
| 416 |
| 417 Handle<FixedArray> code_table = instance->compiled_module()->code_table(); |
| 418 Handle<Code> old_code(Code::cast(code_table->get(func_index)), isolate); |
| 419 interpreted_functions->set(func_index, *new_code); |
| 420 |
| 421 RedirectCallsitesInInstance(isolate, *instance, *old_code, *new_code); |
409 } | 422 } |
410 | 423 |
411 void WasmDebugInfo::PrepareStep(StepAction step_action) { | 424 void WasmDebugInfo::PrepareStep(StepAction step_action) { |
412 GetInterpreterHandle(this)->PrepareStep(step_action); | 425 GetInterpreterHandle(this)->PrepareStep(step_action); |
413 } | 426 } |
414 | 427 |
415 void WasmDebugInfo::RunInterpreter(int func_index, uint8_t* arg_buffer) { | 428 void WasmDebugInfo::RunInterpreter(int func_index, uint8_t* arg_buffer) { |
416 DCHECK_LE(0, func_index); | 429 DCHECK_LE(0, func_index); |
417 GetInterpreterHandle(this)->Execute(static_cast<uint32_t>(func_index), | 430 GetInterpreterHandle(this)->Execute(static_cast<uint32_t>(func_index), |
418 arg_buffer); | 431 arg_buffer); |
419 } | 432 } |
420 | 433 |
421 std::vector<std::pair<uint32_t, int>> WasmDebugInfo::GetInterpretedStack( | 434 std::vector<std::pair<uint32_t, int>> WasmDebugInfo::GetInterpretedStack( |
422 Address frame_pointer) { | 435 Address frame_pointer) { |
423 return GetInterpreterHandle(this)->GetInterpretedStack(frame_pointer); | 436 return GetInterpreterHandle(this)->GetInterpretedStack(frame_pointer); |
424 } | 437 } |
425 | 438 |
426 std::unique_ptr<wasm::InterpretedFrame> WasmDebugInfo::GetInterpretedFrame( | 439 std::unique_ptr<wasm::InterpretedFrame> WasmDebugInfo::GetInterpretedFrame( |
427 Address frame_pointer, int idx) { | 440 Address frame_pointer, int idx) { |
428 return GetInterpreterHandle(this)->GetInterpretedFrame(frame_pointer, idx); | 441 return GetInterpreterHandle(this)->GetInterpretedFrame(frame_pointer, idx); |
429 } | 442 } |
| 443 |
| 444 uint64_t WasmDebugInfo::NumInterpretedCalls() { |
| 445 auto handle = GetInterpreterHandleOrNull(this); |
| 446 return handle ? handle->NumInterpretedCalls() : 0; |
| 447 } |
OLD | NEW |