OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 13564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13575 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin); | 13575 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin); |
13576 Code* code = Code::cast(*p); | 13576 Code* code = Code::cast(*p); |
13577 it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH); | 13577 it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH); |
13578 } else { | 13578 } else { |
13579 it.rinfo()->apply(delta); | 13579 it.rinfo()->apply(delta); |
13580 } | 13580 } |
13581 } | 13581 } |
13582 Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size()); | 13582 Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size()); |
13583 } | 13583 } |
13584 | 13584 |
13585 // Locate the source position which is closest to the code offset. This is | |
13586 // using the source position information embedded in the relocation info. | |
13587 // The position returned is relative to the beginning of the script where the | |
13588 // source for this function is found. | |
13589 int Code::SourcePosition(int code_offset) { | |
13590 int position = RelocInfo::kNoPosition; // Initially no position found. | |
13591 // Subtract one because the current PC is one instruction after the call site. | |
13592 code_offset--; | |
13593 // Find the closest position attached to a pc lower or equal to the current. | |
13594 // Note that the pc of reloc infos grow monotonically. | |
13595 if (kind() == FUNCTION || (is_optimized_code() && !is_turbofanned())) { | |
13596 for (SourcePositionTableIterator it(source_position_table()); | |
13597 !it.done() && it.code_offset() <= code_offset; it.Advance()) { | |
13598 position = it.source_position(); | |
13599 } | |
13600 } else { | |
13601 Address pc = instruction_start() + code_offset; | |
13602 for (RelocIterator it(this, RelocInfo::kPositionMask); | |
13603 !it.done() && it.rinfo()->pc() <= pc; it.next()) { | |
13604 position = static_cast<int>(it.rinfo()->data()); | |
13605 } | |
13606 } | |
13607 DCHECK(kind() == FUNCTION || (is_optimized_code() && is_turbofanned()) || | |
13608 is_wasm_code() || position == RelocInfo::kNoPosition); | |
13609 return position; | |
13610 } | |
13611 | |
13612 | |
13613 // Same as Code::SourcePosition above except it only looks for statement | |
13614 // positions. | |
13615 int Code::SourceStatementPosition(int code_offset) { | |
13616 // First find the closest position. | |
13617 int position = SourcePosition(code_offset); | |
13618 // Now find the closest statement position before the position. | |
13619 int statement_position = 0; | |
13620 if (kind() == FUNCTION || (is_optimized_code() && !is_turbofanned())) { | |
13621 for (SourcePositionTableIterator it(source_position_table()); !it.done(); | |
13622 it.Advance()) { | |
13623 if (it.is_statement()) { | |
13624 int p = it.source_position(); | |
13625 if (statement_position < p && p <= position) { | |
13626 statement_position = p; | |
13627 } | |
13628 } | |
13629 } | |
13630 } else { | |
13631 for (RelocIterator it(this, RelocInfo::kPositionMask); !it.done(); | |
13632 it.next()) { | |
13633 if (RelocInfo::IsStatementPosition(it.rinfo()->rmode())) { | |
13634 int p = static_cast<int>(it.rinfo()->data()); | |
13635 if (statement_position < p && p <= position) { | |
13636 statement_position = p; | |
13637 } | |
13638 } | |
13639 } | |
13640 } | |
13641 return statement_position; | |
13642 } | |
13643 | |
13644 | 13585 |
13645 SafepointEntry Code::GetSafepointEntry(Address pc) { | 13586 SafepointEntry Code::GetSafepointEntry(Address pc) { |
13646 SafepointTable table(this); | 13587 SafepointTable table(this); |
13647 return table.FindEntry(pc); | 13588 return table.FindEntry(pc); |
13648 } | 13589 } |
13649 | 13590 |
13650 | 13591 |
13651 Object* Code::FindNthObject(int n, Map* match_map) { | 13592 Object* Code::FindNthObject(int n, Map* match_map) { |
13652 DCHECK(is_inline_cache_stub()); | 13593 DCHECK(is_inline_cache_stub()); |
13653 DisallowHeapAllocation no_allocation; | 13594 DisallowHeapAllocation no_allocation; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13708 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 13649 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
13709 RelocInfo* info = it.rinfo(); | 13650 RelocInfo* info = it.rinfo(); |
13710 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 13651 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
13711 if (target->is_inline_cache_stub()) { | 13652 if (target->is_inline_cache_stub()) { |
13712 IC::Clear(this->GetIsolate(), info->pc(), info->host()->constant_pool()); | 13653 IC::Clear(this->GetIsolate(), info->pc(), info->host()->constant_pool()); |
13713 } | 13654 } |
13714 } | 13655 } |
13715 } | 13656 } |
13716 | 13657 |
13717 int AbstractCode::SourcePosition(int offset) { | 13658 int AbstractCode::SourcePosition(int offset) { |
13718 return IsBytecodeArray() ? GetBytecodeArray()->SourcePosition(offset) | 13659 int position = 0; |
13719 : GetCode()->SourcePosition(offset); | 13660 // Subtract one because the current PC is one instruction after the call site. |
| 13661 if (IsCode()) offset--; |
| 13662 for (SourcePositionTableIterator iterator(source_position_table()); |
| 13663 !iterator.done() && iterator.code_offset() <= offset; |
| 13664 iterator.Advance()) { |
| 13665 position = iterator.source_position(); |
| 13666 } |
| 13667 return position; |
13720 } | 13668 } |
13721 | 13669 |
13722 int AbstractCode::SourceStatementPosition(int offset) { | 13670 int AbstractCode::SourceStatementPosition(int offset) { |
13723 return IsBytecodeArray() ? GetBytecodeArray()->SourceStatementPosition(offset) | 13671 // First find the closest position. |
13724 : GetCode()->SourceStatementPosition(offset); | 13672 int position = SourcePosition(offset); |
| 13673 // Now find the closest statement position before the position. |
| 13674 int statement_position = 0; |
| 13675 for (SourcePositionTableIterator it(source_position_table()); !it.done(); |
| 13676 it.Advance()) { |
| 13677 if (it.is_statement()) { |
| 13678 int p = it.source_position(); |
| 13679 if (statement_position < p && p <= position) { |
| 13680 statement_position = p; |
| 13681 } |
| 13682 } |
| 13683 } |
| 13684 return statement_position; |
13725 } | 13685 } |
13726 | 13686 |
13727 void JSFunction::ClearTypeFeedbackInfo() { | 13687 void JSFunction::ClearTypeFeedbackInfo() { |
13728 feedback_vector()->ClearSlots(shared()); | 13688 feedback_vector()->ClearSlots(shared()); |
13729 } | 13689 } |
13730 | 13690 |
13731 void JSFunction::ClearTypeFeedbackInfoAtGCTime() { | 13691 void JSFunction::ClearTypeFeedbackInfoAtGCTime() { |
13732 feedback_vector()->ClearSlotsAtGCTime(shared()); | 13692 feedback_vector()->ClearSlotsAtGCTime(shared()); |
13733 } | 13693 } |
13734 | 13694 |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14430 } | 14390 } |
14431 | 14391 |
14432 os << "RelocInfo (size = " << relocation_size() << ")\n"; | 14392 os << "RelocInfo (size = " << relocation_size() << ")\n"; |
14433 for (RelocIterator it(this); !it.done(); it.next()) { | 14393 for (RelocIterator it(this); !it.done(); it.next()) { |
14434 it.rinfo()->Print(GetIsolate(), os); | 14394 it.rinfo()->Print(GetIsolate(), os); |
14435 } | 14395 } |
14436 os << "\n"; | 14396 os << "\n"; |
14437 } | 14397 } |
14438 #endif // ENABLE_DISASSEMBLER | 14398 #endif // ENABLE_DISASSEMBLER |
14439 | 14399 |
14440 int BytecodeArray::SourcePosition(int offset) { | |
14441 int last_position = 0; | |
14442 for (SourcePositionTableIterator iterator(source_position_table()); | |
14443 !iterator.done() && iterator.code_offset() <= offset; | |
14444 iterator.Advance()) { | |
14445 last_position = iterator.source_position(); | |
14446 } | |
14447 return last_position; | |
14448 } | |
14449 | |
14450 int BytecodeArray::SourceStatementPosition(int offset) { | |
14451 // First find the closest position. | |
14452 int position = SourcePosition(offset); | |
14453 // Now find the closest statement position before the position. | |
14454 int statement_position = 0; | |
14455 for (SourcePositionTableIterator it(source_position_table()); !it.done(); | |
14456 it.Advance()) { | |
14457 if (it.is_statement()) { | |
14458 int p = it.source_position(); | |
14459 if (statement_position < p && p <= position) { | |
14460 statement_position = p; | |
14461 } | |
14462 } | |
14463 } | |
14464 return statement_position; | |
14465 } | |
14466 | 14400 |
14467 void BytecodeArray::Disassemble(std::ostream& os) { | 14401 void BytecodeArray::Disassemble(std::ostream& os) { |
14468 os << "Parameter count " << parameter_count() << "\n"; | 14402 os << "Parameter count " << parameter_count() << "\n"; |
14469 os << "Frame size " << frame_size() << "\n"; | 14403 os << "Frame size " << frame_size() << "\n"; |
14470 | 14404 |
14471 const uint8_t* base_address = GetFirstBytecodeAddress(); | 14405 const uint8_t* base_address = GetFirstBytecodeAddress(); |
14472 SourcePositionTableIterator source_positions(source_position_table()); | 14406 SourcePositionTableIterator source_positions(source_position_table()); |
14473 | 14407 |
14474 interpreter::BytecodeArrayIterator iterator(handle(this)); | 14408 interpreter::BytecodeArrayIterator iterator(handle(this)); |
14475 while (!iterator.done()) { | 14409 while (!iterator.done()) { |
(...skipping 4487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18963 if (cell->value() != *new_value) { | 18897 if (cell->value() != *new_value) { |
18964 cell->set_value(*new_value); | 18898 cell->set_value(*new_value); |
18965 Isolate* isolate = cell->GetIsolate(); | 18899 Isolate* isolate = cell->GetIsolate(); |
18966 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18900 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18967 isolate, DependentCode::kPropertyCellChangedGroup); | 18901 isolate, DependentCode::kPropertyCellChangedGroup); |
18968 } | 18902 } |
18969 } | 18903 } |
18970 | 18904 |
18971 int JSGeneratorObject::source_position() const { | 18905 int JSGeneratorObject::source_position() const { |
18972 CHECK(is_suspended()); | 18906 CHECK(is_suspended()); |
| 18907 AbstractCode* code; |
| 18908 int code_offset; |
18973 if (function()->shared()->HasBytecodeArray()) { | 18909 if (function()->shared()->HasBytecodeArray()) { |
18974 // New-style generators. | 18910 // New-style generators. |
18975 int offset = Smi::cast(input_or_debug_pos())->value(); | 18911 code_offset = Smi::cast(input_or_debug_pos())->value(); |
18976 // The stored bytecode offset is relative to a different base than what | 18912 // The stored bytecode offset is relative to a different base than what |
18977 // is used in the source position table, hence the subtraction. | 18913 // is used in the source position table, hence the subtraction. |
18978 offset -= BytecodeArray::kHeaderSize - kHeapObjectTag; | 18914 code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag; |
18979 return function()->shared()->bytecode_array()->SourcePosition(offset); | 18915 code = AbstractCode::cast(function()->shared()->bytecode_array()); |
18980 } else { | 18916 } else { |
18981 // Old-style generators. | 18917 // Old-style generators. |
18982 int offset = continuation(); | 18918 code_offset = continuation(); |
18983 CHECK(0 <= offset && offset < function()->code()->instruction_size()); | 18919 CHECK(0 <= code_offset); |
18984 return function()->code()->SourcePosition(offset); | 18920 CHECK(code_offset < function()->code()->instruction_size()); |
| 18921 code = AbstractCode::cast(function()->shared()->code()); |
18985 } | 18922 } |
| 18923 return code->SourcePosition(code_offset); |
18986 } | 18924 } |
18987 | 18925 |
18988 // static | 18926 // static |
18989 AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate, | 18927 AccessCheckInfo* AccessCheckInfo::Get(Isolate* isolate, |
18990 Handle<JSObject> receiver) { | 18928 Handle<JSObject> receiver) { |
18991 DisallowHeapAllocation no_gc; | 18929 DisallowHeapAllocation no_gc; |
18992 DCHECK(receiver->map()->is_access_check_needed()); | 18930 DCHECK(receiver->map()->is_access_check_needed()); |
18993 Object* maybe_constructor = receiver->map()->GetConstructor(); | 18931 Object* maybe_constructor = receiver->map()->GetConstructor(); |
18994 // Might happen for a detached context. | 18932 // Might happen for a detached context. |
18995 if (!maybe_constructor->IsJSFunction()) return nullptr; | 18933 if (!maybe_constructor->IsJSFunction()) return nullptr; |
18996 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 18934 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
18997 // Might happen for the debug context. | 18935 // Might happen for the debug context. |
18998 if (!constructor->shared()->IsApiFunction()) return nullptr; | 18936 if (!constructor->shared()->IsApiFunction()) return nullptr; |
18999 | 18937 |
19000 Object* data_obj = | 18938 Object* data_obj = |
19001 constructor->shared()->get_api_func_data()->access_check_info(); | 18939 constructor->shared()->get_api_func_data()->access_check_info(); |
19002 if (data_obj->IsUndefined(isolate)) return nullptr; | 18940 if (data_obj->IsUndefined(isolate)) return nullptr; |
19003 | 18941 |
19004 return AccessCheckInfo::cast(data_obj); | 18942 return AccessCheckInfo::cast(data_obj); |
19005 } | 18943 } |
19006 | 18944 |
19007 } // namespace internal | 18945 } // namespace internal |
19008 } // namespace v8 | 18946 } // namespace v8 |
OLD | NEW |