diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-08-01 08:38:30 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-08-01 12:53:56 +0200 |
commit | 2dcc3665abf57c3607cebffdeeca062f5894885d (patch) | |
tree | 4f560748132edcfb4c22d6f967a7e80d23d7ea2c /deps/v8/src/codegen/handler-table.cc | |
parent | 1ee47d550c6de132f06110aa13eceb7551d643b3 (diff) | |
download | node-new-2dcc3665abf57c3607cebffdeeca062f5894885d.tar.gz |
deps: update V8 to 7.6.303.28
PR-URL: https://github.com/nodejs/node/pull/28016
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Diffstat (limited to 'deps/v8/src/codegen/handler-table.cc')
-rw-r--r-- | deps/v8/src/codegen/handler-table.cc | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/deps/v8/src/codegen/handler-table.cc b/deps/v8/src/codegen/handler-table.cc new file mode 100644 index 0000000000..12a05e1fba --- /dev/null +++ b/deps/v8/src/codegen/handler-table.cc @@ -0,0 +1,220 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/codegen/handler-table.h" + +#include <iomanip> + +#include "src/codegen/assembler-inl.h" +#include "src/objects/code-inl.h" +#include "src/objects/objects-inl.h" + +namespace v8 { +namespace internal { + +HandlerTable::HandlerTable(Code code) + : HandlerTable(code.InstructionStart() + code.handler_table_offset(), + code.handler_table_size()) {} + +HandlerTable::HandlerTable(BytecodeArray bytecode_array) + : HandlerTable(bytecode_array.handler_table()) {} + +HandlerTable::HandlerTable(ByteArray byte_array) + : number_of_entries_(byte_array.length() / kRangeEntrySize / + sizeof(int32_t)), +#ifdef DEBUG + mode_(kRangeBasedEncoding), +#endif + raw_encoded_data_( + reinterpret_cast<Address>(byte_array.GetDataStartAddress())) { + DCHECK_EQ(0, byte_array.length() % (kRangeEntrySize * sizeof(int32_t))); +} + +HandlerTable::HandlerTable(Address handler_table, int handler_table_size) + : number_of_entries_(handler_table_size / kReturnEntrySize / + sizeof(int32_t)), +#ifdef DEBUG + mode_(kReturnAddressBasedEncoding), +#endif + raw_encoded_data_(handler_table) { + static_assert(4 < kReturnEntrySize * sizeof(int32_t), "allowed padding"); + DCHECK_GE(4, handler_table_size % (kReturnEntrySize * sizeof(int32_t))); +} + +int HandlerTable::GetRangeStart(int index) const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + DCHECK_LT(index, NumberOfRangeEntries()); + int offset = index * kRangeEntrySize + kRangeStartIndex; + return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)); +} + +int HandlerTable::GetRangeEnd(int index) const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + DCHECK_LT(index, NumberOfRangeEntries()); + int offset = index * kRangeEntrySize + kRangeEndIndex; + return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)); +} + +int HandlerTable::GetRangeHandler(int index) const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + DCHECK_LT(index, NumberOfRangeEntries()); + int offset = index * kRangeEntrySize + kRangeHandlerIndex; + return HandlerOffsetField::decode( + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t))); +} + +int HandlerTable::GetRangeData(int index) const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + DCHECK_LT(index, NumberOfRangeEntries()); + int offset = index * kRangeEntrySize + kRangeDataIndex; + return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)); +} + +HandlerTable::CatchPrediction HandlerTable::GetRangePrediction( + int index) const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + DCHECK_LT(index, NumberOfRangeEntries()); + int offset = index * kRangeEntrySize + kRangeHandlerIndex; + return HandlerPredictionField::decode( + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t))); +} + +int HandlerTable::GetReturnOffset(int index) const { + DCHECK_EQ(kReturnAddressBasedEncoding, mode_); + DCHECK_LT(index, NumberOfReturnEntries()); + int offset = index * kReturnEntrySize + kReturnOffsetIndex; + return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)); +} + +int HandlerTable::GetReturnHandler(int index) const { + DCHECK_EQ(kReturnAddressBasedEncoding, mode_); + DCHECK_LT(index, NumberOfReturnEntries()); + int offset = index * kReturnEntrySize + kReturnHandlerIndex; + return HandlerOffsetField::decode( + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t))); +} + +void HandlerTable::SetRangeStart(int index, int value) { + int offset = index * kRangeEntrySize + kRangeStartIndex; + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value; +} + +void HandlerTable::SetRangeEnd(int index, int value) { + int offset = index * kRangeEntrySize + kRangeEndIndex; + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value; +} + +void HandlerTable::SetRangeHandler(int index, int handler_offset, + CatchPrediction prediction) { + int value = HandlerOffsetField::encode(handler_offset) | + HandlerPredictionField::encode(prediction); + int offset = index * kRangeEntrySize + kRangeHandlerIndex; + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value; +} + +void HandlerTable::SetRangeData(int index, int value) { + int offset = index * kRangeEntrySize + kRangeDataIndex; + Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value; +} + +// static +int HandlerTable::LengthForRange(int entries) { + return entries * kRangeEntrySize * sizeof(int32_t); +} + +// static +int HandlerTable::EmitReturnTableStart(Assembler* masm) { + masm->DataAlign(sizeof(int32_t)); // Make sure entries are aligned. + masm->RecordComment(";;; Exception handler table."); + int table_start = masm->pc_offset(); + return table_start; +} + +// static +void HandlerTable::EmitReturnEntry(Assembler* masm, int offset, int handler) { + masm->dd(offset); + masm->dd(HandlerOffsetField::encode(handler)); +} + +int HandlerTable::NumberOfRangeEntries() const { + DCHECK_EQ(kRangeBasedEncoding, mode_); + return number_of_entries_; +} + +int HandlerTable::NumberOfReturnEntries() const { + DCHECK_EQ(kReturnAddressBasedEncoding, mode_); + return number_of_entries_; +} + +int HandlerTable::LookupRange(int pc_offset, int* data_out, + CatchPrediction* prediction_out) { + int innermost_handler = -1; +#ifdef DEBUG + // Assuming that ranges are well nested, we don't need to track the innermost + // offsets. This is just to verify that the table is actually well nested. + int innermost_start = std::numeric_limits<int>::min(); + int innermost_end = std::numeric_limits<int>::max(); +#endif + for (int i = 0; i < NumberOfRangeEntries(); ++i) { + int start_offset = GetRangeStart(i); + int end_offset = GetRangeEnd(i); + int handler_offset = GetRangeHandler(i); + int handler_data = GetRangeData(i); + CatchPrediction prediction = GetRangePrediction(i); + if (pc_offset >= start_offset && pc_offset < end_offset) { + DCHECK_GE(start_offset, innermost_start); + DCHECK_LT(end_offset, innermost_end); + innermost_handler = handler_offset; +#ifdef DEBUG + innermost_start = start_offset; + innermost_end = end_offset; +#endif + if (data_out) *data_out = handler_data; + if (prediction_out) *prediction_out = prediction; + } + } + return innermost_handler; +} + +// TODO(turbofan): Make sure table is sorted and use binary search. +int HandlerTable::LookupReturn(int pc_offset) { + for (int i = 0; i < NumberOfReturnEntries(); ++i) { + int return_offset = GetReturnOffset(i); + if (pc_offset == return_offset) { + return GetReturnHandler(i); + } + } + return -1; +} + +#ifdef ENABLE_DISASSEMBLER + +void HandlerTable::HandlerTableRangePrint(std::ostream& os) { + os << " from to hdlr (prediction, data)\n"; + for (int i = 0; i < NumberOfRangeEntries(); ++i) { + int pc_start = GetRangeStart(i); + int pc_end = GetRangeEnd(i); + int handler_offset = GetRangeHandler(i); + int handler_data = GetRangeData(i); + CatchPrediction prediction = GetRangePrediction(i); + os << " (" << std::setw(4) << pc_start << "," << std::setw(4) << pc_end + << ") -> " << std::setw(4) << handler_offset + << " (prediction=" << prediction << ", data=" << handler_data << ")\n"; + } +} + +void HandlerTable::HandlerTableReturnPrint(std::ostream& os) { + os << " offset handler\n"; + for (int i = 0; i < NumberOfReturnEntries(); ++i) { + int pc_offset = GetReturnOffset(i); + int handler_offset = GetReturnHandler(i); + os << std::hex << " " << std::setw(4) << pc_offset << " -> " + << std::setw(4) << handler_offset << std::dec << "\n"; + } +} + +#endif // ENABLE_DISASSEMBLER + +} // namespace internal +} // namespace v8 |