5 #include "src/handler-table.h" 9 #include "src/assembler-inl.h" 10 #include "src/objects-inl.h" 11 #include "src/objects/code-inl.h" 16 HandlerTable::HandlerTable(Code code)
17 : HandlerTable(code->InstructionStart(), code->handler_table_offset()) {}
19 HandlerTable::HandlerTable(BytecodeArray bytecode_array)
20 : HandlerTable(bytecode_array->handler_table()) {}
22 HandlerTable::HandlerTable(ByteArray byte_array)
23 : number_of_entries_(byte_array->length() / kRangeEntrySize /
26 mode_(kRangeBasedEncoding),
29 reinterpret_cast<Address>(byte_array->GetDataStartAddress())) {
32 HandlerTable::HandlerTable(Address instruction_start,
33 size_t handler_table_offset)
34 : number_of_entries_(0),
36 mode_(kReturnAddressBasedEncoding),
38 raw_encoded_data_(instruction_start + handler_table_offset) {
39 if (handler_table_offset > 0) {
40 number_of_entries_ = Memory<int32_t>(raw_encoded_data_);
41 raw_encoded_data_ +=
sizeof(int32_t);
45 int HandlerTable::GetRangeStart(
int index)
const {
46 DCHECK_EQ(kRangeBasedEncoding, mode_);
47 DCHECK_LT(index, NumberOfRangeEntries());
48 int offset = index * kRangeEntrySize + kRangeStartIndex;
49 return Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t));
52 int HandlerTable::GetRangeEnd(
int index)
const {
53 DCHECK_EQ(kRangeBasedEncoding, mode_);
54 DCHECK_LT(index, NumberOfRangeEntries());
55 int offset = index * kRangeEntrySize + kRangeEndIndex;
56 return Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t));
59 int HandlerTable::GetRangeHandler(
int index)
const {
60 DCHECK_EQ(kRangeBasedEncoding, mode_);
61 DCHECK_LT(index, NumberOfRangeEntries());
62 int offset = index * kRangeEntrySize + kRangeHandlerIndex;
63 return HandlerOffsetField::decode(
64 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)));
67 int HandlerTable::GetRangeData(
int index)
const {
68 DCHECK_EQ(kRangeBasedEncoding, mode_);
69 DCHECK_LT(index, NumberOfRangeEntries());
70 int offset = index * kRangeEntrySize + kRangeDataIndex;
71 return Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t));
74 HandlerTable::CatchPrediction HandlerTable::GetRangePrediction(
76 DCHECK_EQ(kRangeBasedEncoding, mode_);
77 DCHECK_LT(index, NumberOfRangeEntries());
78 int offset = index * kRangeEntrySize + kRangeHandlerIndex;
79 return HandlerPredictionField::decode(
80 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)));
83 int HandlerTable::GetReturnOffset(
int index)
const {
84 DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
85 DCHECK_LT(index, NumberOfReturnEntries());
86 int offset = index * kReturnEntrySize + kReturnOffsetIndex;
87 return Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t));
90 int HandlerTable::GetReturnHandler(
int index)
const {
91 DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
92 DCHECK_LT(index, NumberOfReturnEntries());
93 int offset = index * kReturnEntrySize + kReturnHandlerIndex;
94 return HandlerOffsetField::decode(
95 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)));
98 void HandlerTable::SetRangeStart(
int index,
int value) {
99 int offset = index * kRangeEntrySize + kRangeStartIndex;
100 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)) = value;
103 void HandlerTable::SetRangeEnd(
int index,
int value) {
104 int offset = index * kRangeEntrySize + kRangeEndIndex;
105 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)) = value;
108 void HandlerTable::SetRangeHandler(
int index,
int handler_offset,
109 CatchPrediction prediction) {
110 int value = HandlerOffsetField::encode(handler_offset) |
111 HandlerPredictionField::encode(prediction);
112 int offset = index * kRangeEntrySize + kRangeHandlerIndex;
113 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)) = value;
116 void HandlerTable::SetRangeData(
int index,
int value) {
117 int offset = index * kRangeEntrySize + kRangeDataIndex;
118 Memory<int32_t>(raw_encoded_data_ + offset *
sizeof(int32_t)) = value;
122 int HandlerTable::LengthForRange(
int entries) {
123 return entries * kRangeEntrySize *
sizeof(int32_t);
127 int HandlerTable::EmitReturnTableStart(Assembler* masm,
int entries) {
128 masm->DataAlign(
sizeof(int32_t));
129 masm->RecordComment(
";;; Exception handler table.");
130 int table_start = masm->pc_offset();
136 void HandlerTable::EmitReturnEntry(Assembler* masm,
int offset,
int handler) {
138 masm->dd(HandlerOffsetField::encode(handler));
141 int HandlerTable::NumberOfRangeEntries()
const {
142 DCHECK_EQ(kRangeBasedEncoding, mode_);
143 return number_of_entries_;
146 int HandlerTable::NumberOfReturnEntries()
const {
147 DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
148 return number_of_entries_;
151 int HandlerTable::LookupRange(
int pc_offset,
int* data_out,
152 CatchPrediction* prediction_out) {
153 int innermost_handler = -1;
157 int innermost_start = std::numeric_limits<int>::min();
158 int innermost_end = std::numeric_limits<int>::max();
160 for (
int i = 0;
i < NumberOfRangeEntries(); ++
i) {
161 int start_offset = GetRangeStart(
i);
162 int end_offset = GetRangeEnd(
i);
163 int handler_offset = GetRangeHandler(
i);
164 int handler_data = GetRangeData(
i);
165 CatchPrediction prediction = GetRangePrediction(
i);
166 if (pc_offset >= start_offset && pc_offset < end_offset) {
167 DCHECK_GE(start_offset, innermost_start);
168 DCHECK_LT(end_offset, innermost_end);
169 innermost_handler = handler_offset;
171 innermost_start = start_offset;
172 innermost_end = end_offset;
174 if (data_out) *data_out = handler_data;
175 if (prediction_out) *prediction_out = prediction;
178 return innermost_handler;
182 int HandlerTable::LookupReturn(
int pc_offset) {
183 for (
int i = 0;
i < NumberOfReturnEntries(); ++
i) {
184 int return_offset = GetReturnOffset(
i);
185 if (pc_offset == return_offset) {
186 return GetReturnHandler(
i);
192 #ifdef ENABLE_DISASSEMBLER 194 void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
195 os <<
" from to hdlr (prediction, data)\n";
196 for (
int i = 0;
i < NumberOfRangeEntries(); ++
i) {
197 int pc_start = GetRangeStart(
i);
198 int pc_end = GetRangeEnd(
i);
199 int handler_offset = GetRangeHandler(
i);
200 int handler_data = GetRangeData(
i);
201 CatchPrediction prediction = GetRangePrediction(
i);
202 os <<
" (" << std::setw(4) << pc_start <<
"," << std::setw(4) << pc_end
203 <<
") -> " << std::setw(4) << handler_offset
204 <<
" (prediction=" << prediction <<
", data=" << handler_data <<
")\n";
208 void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
209 os <<
" offset handler\n";
210 for (
int i = 0;
i < NumberOfReturnEntries(); ++
i) {
211 int pc_offset = GetReturnOffset(
i);
212 int handler_offset = GetReturnHandler(
i);
213 os << std::hex <<
" " << std::setw(4) << pc_offset <<
" -> " 214 << std::setw(4) << handler_offset << std::dec <<
"\n";
218 #endif // ENABLE_DISASSEMBLER