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 |