| OLD | NEW |
| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "api.h" | 7 #include "api.h" |
| 8 #include "arguments.h" | 8 #include "arguments.h" |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { | 373 bool BreakLocationIterator::IsStepInLocation(Isolate* isolate) { |
| 374 if (RelocInfo::IsConstructCall(original_rmode())) { | 374 if (RelocInfo::IsConstructCall(original_rmode())) { |
| 375 return true; | 375 return true; |
| 376 } else if (RelocInfo::IsCodeTarget(rmode())) { | 376 } else if (RelocInfo::IsCodeTarget(rmode())) { |
| 377 HandleScope scope(debug_info_->GetIsolate()); | 377 HandleScope scope(debug_info_->GetIsolate()); |
| 378 Address target = original_rinfo()->target_address(); | 378 Address target = original_rinfo()->target_address(); |
| 379 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); | 379 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target)); |
| 380 if (target_code->kind() == Code::STUB) { | 380 if (target_code->kind() == Code::STUB) { |
| 381 return target_code->major_key() == CodeStub::CallFunction; | 381 return target_code->major_key() == CodeStub::CallFunction; |
| 382 } | 382 } |
| 383 return target_code->is_call_stub(); |
| 383 } | 384 } |
| 384 return false; | 385 return false; |
| 385 } | 386 } |
| 386 | 387 |
| 387 | 388 |
| 388 void BreakLocationIterator::PrepareStepIn(Isolate* isolate) { | 389 void BreakLocationIterator::PrepareStepIn(Isolate* isolate) { |
| 389 #ifdef DEBUG | 390 #ifdef DEBUG |
| 390 HandleScope scope(isolate); | 391 HandleScope scope(isolate); |
| 391 // Step in can only be prepared if currently positioned on an IC call, | 392 // Step in can only be prepared if currently positioned on an IC call, |
| 392 // construct call or CallFunction stub call. | 393 // construct call or CallFunction stub call. |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1387 bool is_load_or_store = false; | 1388 bool is_load_or_store = false; |
| 1388 bool is_inline_cache_stub = false; | 1389 bool is_inline_cache_stub = false; |
| 1389 bool is_at_restarted_function = false; | 1390 bool is_at_restarted_function = false; |
| 1390 Handle<Code> call_function_stub; | 1391 Handle<Code> call_function_stub; |
| 1391 | 1392 |
| 1392 if (thread_local_.restarter_frame_function_pointer_ == NULL) { | 1393 if (thread_local_.restarter_frame_function_pointer_ == NULL) { |
| 1393 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { | 1394 if (RelocInfo::IsCodeTarget(it.rinfo()->rmode())) { |
| 1394 bool is_call_target = false; | 1395 bool is_call_target = false; |
| 1395 Address target = it.rinfo()->target_address(); | 1396 Address target = it.rinfo()->target_address(); |
| 1396 Code* code = Code::GetCodeFromTargetAddress(target); | 1397 Code* code = Code::GetCodeFromTargetAddress(target); |
| 1398 if (code->is_call_stub()) { |
| 1399 is_call_target = true; |
| 1400 } |
| 1397 if (code->is_inline_cache_stub()) { | 1401 if (code->is_inline_cache_stub()) { |
| 1398 is_inline_cache_stub = true; | 1402 is_inline_cache_stub = true; |
| 1399 is_load_or_store = !is_call_target; | 1403 is_load_or_store = !is_call_target; |
| 1400 } | 1404 } |
| 1401 | 1405 |
| 1402 // Check if target code is CallFunction stub. | 1406 // Check if target code is CallFunction stub. |
| 1403 Code* maybe_call_function_stub = code; | 1407 Code* maybe_call_function_stub = code; |
| 1404 // If there is a breakpoint at this line look at the original code to | 1408 // If there is a breakpoint at this line look at the original code to |
| 1405 // check if it is a CallFunction stub. | 1409 // check if it is a CallFunction stub. |
| 1406 if (it.IsDebugBreak()) { | 1410 if (it.IsDebugBreak()) { |
| 1407 Address original_target = it.original_rinfo()->target_address(); | 1411 Address original_target = it.original_rinfo()->target_address(); |
| 1408 maybe_call_function_stub = | 1412 maybe_call_function_stub = |
| 1409 Code::GetCodeFromTargetAddress(original_target); | 1413 Code::GetCodeFromTargetAddress(original_target); |
| 1410 } | 1414 } |
| 1411 if (maybe_call_function_stub->kind() == Code::STUB && | 1415 if ((maybe_call_function_stub->kind() == Code::STUB && |
| 1412 maybe_call_function_stub->major_key() == CodeStub::CallFunction) { | 1416 maybe_call_function_stub->major_key() == CodeStub::CallFunction) || |
| 1417 maybe_call_function_stub->kind() == Code::CALL_IC) { |
| 1413 // Save reference to the code as we may need it to find out arguments | 1418 // Save reference to the code as we may need it to find out arguments |
| 1414 // count for 'step in' later. | 1419 // count for 'step in' later. |
| 1415 call_function_stub = Handle<Code>(maybe_call_function_stub); | 1420 call_function_stub = Handle<Code>(maybe_call_function_stub); |
| 1416 } | 1421 } |
| 1417 } | 1422 } |
| 1418 } else { | 1423 } else { |
| 1419 is_at_restarted_function = true; | 1424 is_at_restarted_function = true; |
| 1420 } | 1425 } |
| 1421 | 1426 |
| 1422 // If this is the last break code target step out is the only possibility. | 1427 // If this is the last break code target step out is the only possibility. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1458 } else { | 1463 } else { |
| 1459 // If there's restarter frame on top of the stack, just get the pointer | 1464 // If there's restarter frame on top of the stack, just get the pointer |
| 1460 // to function which is going to be restarted. | 1465 // to function which is going to be restarted. |
| 1461 if (is_at_restarted_function) { | 1466 if (is_at_restarted_function) { |
| 1462 Handle<JSFunction> restarted_function( | 1467 Handle<JSFunction> restarted_function( |
| 1463 JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); | 1468 JSFunction::cast(*thread_local_.restarter_frame_function_pointer_)); |
| 1464 FloodWithOneShot(restarted_function); | 1469 FloodWithOneShot(restarted_function); |
| 1465 } else if (!call_function_stub.is_null()) { | 1470 } else if (!call_function_stub.is_null()) { |
| 1466 // If it's CallFunction stub ensure target function is compiled and flood | 1471 // If it's CallFunction stub ensure target function is compiled and flood |
| 1467 // it with one shot breakpoints. | 1472 // it with one shot breakpoints. |
| 1473 bool is_call_ic = call_function_stub->kind() == Code::CALL_IC; |
| 1468 | 1474 |
| 1469 // Find out number of arguments from the stub minor key. | 1475 // Find out number of arguments from the stub minor key. |
| 1470 // Reverse lookup required as the minor key cannot be retrieved | 1476 // Reverse lookup required as the minor key cannot be retrieved |
| 1471 // from the code object. | 1477 // from the code object. |
| 1472 Handle<Object> obj( | 1478 Handle<Object> obj( |
| 1473 isolate_->heap()->code_stubs()->SlowReverseLookup( | 1479 isolate_->heap()->code_stubs()->SlowReverseLookup( |
| 1474 *call_function_stub), | 1480 *call_function_stub), |
| 1475 isolate_); | 1481 isolate_); |
| 1476 ASSERT(!obj.is_null()); | 1482 ASSERT(!obj.is_null()); |
| 1477 ASSERT(!(*obj)->IsUndefined()); | 1483 ASSERT(!(*obj)->IsUndefined()); |
| 1478 ASSERT(obj->IsSmi()); | 1484 ASSERT(obj->IsSmi()); |
| 1479 // Get the STUB key and extract major and minor key. | 1485 // Get the STUB key and extract major and minor key. |
| 1480 uint32_t key = Smi::cast(*obj)->value(); | 1486 uint32_t key = Smi::cast(*obj)->value(); |
| 1481 // Argc in the stub is the number of arguments passed - not the | 1487 // Argc in the stub is the number of arguments passed - not the |
| 1482 // expected arguments of the called function. | 1488 // expected arguments of the called function. |
| 1483 int call_function_arg_count = | 1489 int call_function_arg_count = is_call_ic |
| 1484 CallFunctionStub::ExtractArgcFromMinorKey( | 1490 ? CallICStub::ExtractArgcFromMinorKey(CodeStub::MinorKeyFromKey(key)) |
| 1491 : CallFunctionStub::ExtractArgcFromMinorKey( |
| 1485 CodeStub::MinorKeyFromKey(key)); | 1492 CodeStub::MinorKeyFromKey(key)); |
| 1486 ASSERT(call_function_stub->major_key() == | 1493 |
| 1487 CodeStub::MajorKeyFromKey(key)); | 1494 ASSERT(is_call_ic || |
| 1495 call_function_stub->major_key() == CodeStub::MajorKeyFromKey(key)); |
| 1488 | 1496 |
| 1489 // Find target function on the expression stack. | 1497 // Find target function on the expression stack. |
| 1490 // Expression stack looks like this (top to bottom): | 1498 // Expression stack looks like this (top to bottom): |
| 1491 // argN | 1499 // argN |
| 1492 // ... | 1500 // ... |
| 1493 // arg0 | 1501 // arg0 |
| 1494 // Receiver | 1502 // Receiver |
| 1495 // Function to call | 1503 // Function to call |
| 1496 int expressions_count = frame->ComputeExpressionsCount(); | 1504 int expressions_count = frame->ComputeExpressionsCount(); |
| 1497 ASSERT(expressions_count - 2 - call_function_arg_count >= 0); | 1505 ASSERT(expressions_count - 2 - call_function_arg_count >= 0); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 | 1613 |
| 1606 | 1614 |
| 1607 // Find the builtin to use for invoking the debug break | 1615 // Find the builtin to use for invoking the debug break |
| 1608 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { | 1616 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) { |
| 1609 Isolate* isolate = code->GetIsolate(); | 1617 Isolate* isolate = code->GetIsolate(); |
| 1610 | 1618 |
| 1611 // Find the builtin debug break function matching the calling convention | 1619 // Find the builtin debug break function matching the calling convention |
| 1612 // used by the call site. | 1620 // used by the call site. |
| 1613 if (code->is_inline_cache_stub()) { | 1621 if (code->is_inline_cache_stub()) { |
| 1614 switch (code->kind()) { | 1622 switch (code->kind()) { |
| 1623 case Code::CALL_IC: |
| 1624 return isolate->builtins()->CallICStub_DebugBreak(); |
| 1625 |
| 1615 case Code::LOAD_IC: | 1626 case Code::LOAD_IC: |
| 1616 return isolate->builtins()->LoadIC_DebugBreak(); | 1627 return isolate->builtins()->LoadIC_DebugBreak(); |
| 1617 | 1628 |
| 1618 case Code::STORE_IC: | 1629 case Code::STORE_IC: |
| 1619 return isolate->builtins()->StoreIC_DebugBreak(); | 1630 return isolate->builtins()->StoreIC_DebugBreak(); |
| 1620 | 1631 |
| 1621 case Code::KEYED_LOAD_IC: | 1632 case Code::KEYED_LOAD_IC: |
| 1622 return isolate->builtins()->KeyedLoadIC_DebugBreak(); | 1633 return isolate->builtins()->KeyedLoadIC_DebugBreak(); |
| 1623 | 1634 |
| 1624 case Code::KEYED_STORE_IC: | 1635 case Code::KEYED_STORE_IC: |
| 1625 return isolate->builtins()->KeyedStoreIC_DebugBreak(); | 1636 return isolate->builtins()->KeyedStoreIC_DebugBreak(); |
| 1626 | 1637 |
| 1627 case Code::COMPARE_NIL_IC: | 1638 case Code::COMPARE_NIL_IC: |
| 1628 return isolate->builtins()->CompareNilIC_DebugBreak(); | 1639 return isolate->builtins()->CompareNilIC_DebugBreak(); |
| 1629 | 1640 |
| 1630 default: | 1641 default: |
| 1631 UNREACHABLE(); | 1642 UNREACHABLE(); |
| 1632 } | 1643 } |
| 1633 } | 1644 } |
| 1634 if (RelocInfo::IsConstructCall(mode)) { | 1645 if (RelocInfo::IsConstructCall(mode)) { |
| 1635 if (code->has_function_cache()) { | 1646 if (code->has_function_cache()) { |
| 1636 return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); | 1647 return isolate->builtins()->CallConstructStub_Recording_DebugBreak(); |
| 1637 } else { | 1648 } else { |
| 1638 return isolate->builtins()->CallConstructStub_DebugBreak(); | 1649 return isolate->builtins()->CallConstructStub_DebugBreak(); |
| 1639 } | 1650 } |
| 1640 } | 1651 } |
| 1641 if (code->kind() == Code::STUB) { | 1652 if (code->kind() == Code::STUB) { |
| 1642 ASSERT(code->major_key() == CodeStub::CallFunction); | 1653 ASSERT(code->major_key() == CodeStub::CallFunction); |
| 1643 if (code->has_function_cache()) { | 1654 return isolate->builtins()->CallFunctionStub_DebugBreak(); |
| 1644 return isolate->builtins()->CallFunctionStub_Recording_DebugBreak(); | |
| 1645 } else { | |
| 1646 return isolate->builtins()->CallFunctionStub_DebugBreak(); | |
| 1647 } | |
| 1648 } | 1655 } |
| 1649 | 1656 |
| 1650 UNREACHABLE(); | 1657 UNREACHABLE(); |
| 1651 return Handle<Code>::null(); | 1658 return Handle<Code>::null(); |
| 1652 } | 1659 } |
| 1653 | 1660 |
| 1654 | 1661 |
| 1655 // Simple function for returning the source positions for active break points. | 1662 // Simple function for returning the source positions for active break points. |
| 1656 Handle<Object> Debug::GetSourceBreakLocations( | 1663 Handle<Object> Debug::GetSourceBreakLocations( |
| 1657 Handle<SharedFunctionInfo> shared, | 1664 Handle<SharedFunctionInfo> shared, |
| (...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3720 already_signalled_ = false; | 3727 already_signalled_ = false; |
| 3721 } | 3728 } |
| 3722 { | 3729 { |
| 3723 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3730 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3724 isolate_->debugger()->CallMessageDispatchHandler(); | 3731 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3725 } | 3732 } |
| 3726 } | 3733 } |
| 3727 } | 3734 } |
| 3728 | 3735 |
| 3729 } } // namespace v8::internal | 3736 } } // namespace v8::internal |
| OLD | NEW |