11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_HANDLER_TABLE_H_ 61cb0ef41Sopenharmony_ci#define V8_CODEGEN_HANDLER_TABLE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/bit-field.h" 91cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h" 101cb0ef41Sopenharmony_ci#include "src/common/globals.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass Assembler; 161cb0ef41Sopenharmony_ciclass ByteArray; 171cb0ef41Sopenharmony_ciclass BytecodeArray; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cinamespace wasm { 201cb0ef41Sopenharmony_ciclass WasmCode; 211cb0ef41Sopenharmony_ci} // namespace wasm 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci// HandlerTable is a byte array containing entries for exception handlers in 241cb0ef41Sopenharmony_ci// the code object it is associated with. The tables come in two flavors: 251cb0ef41Sopenharmony_ci// 1) Based on ranges: Used for unoptimized code. Stored in a {ByteArray} that 261cb0ef41Sopenharmony_ci// is attached to each {BytecodeArray}. Contains one entry per exception 271cb0ef41Sopenharmony_ci// handler and a range representing the try-block covered by that handler. 281cb0ef41Sopenharmony_ci// Layout looks as follows: 291cb0ef41Sopenharmony_ci// [ range-start , range-end , handler-offset , handler-data ] 301cb0ef41Sopenharmony_ci// 2) Based on return addresses: Used for turbofanned code. Stored directly in 311cb0ef41Sopenharmony_ci// the instruction stream of the {Code} object. Contains one entry per 321cb0ef41Sopenharmony_ci// call-site that could throw an exception. Layout looks as follows: 331cb0ef41Sopenharmony_ci// [ return-address-offset , handler-offset ] 341cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE HandlerTable { 351cb0ef41Sopenharmony_ci public: 361cb0ef41Sopenharmony_ci // Conservative prediction whether a given handler will locally catch an 371cb0ef41Sopenharmony_ci // exception or cause a re-throw to outside the code boundary. Since this is 381cb0ef41Sopenharmony_ci // undecidable it is merely an approximation (e.g. useful for debugger). 391cb0ef41Sopenharmony_ci enum CatchPrediction { 401cb0ef41Sopenharmony_ci UNCAUGHT, // The handler will (likely) rethrow the exception. 411cb0ef41Sopenharmony_ci CAUGHT, // The exception will be caught by the handler. 421cb0ef41Sopenharmony_ci PROMISE, // The exception will be caught and cause a promise rejection. 431cb0ef41Sopenharmony_ci ASYNC_AWAIT, // The exception will be caught and cause a promise rejection 441cb0ef41Sopenharmony_ci // in the desugaring of an async function, so special 451cb0ef41Sopenharmony_ci // async/await handling in the debugger can take place. 461cb0ef41Sopenharmony_ci UNCAUGHT_ASYNC_AWAIT, // The exception will be caught and cause a promise 471cb0ef41Sopenharmony_ci // rejection in the desugaring of an async REPL 481cb0ef41Sopenharmony_ci // script. The corresponding message object needs to 491cb0ef41Sopenharmony_ci // be kept alive on the Isolate though. 501cb0ef41Sopenharmony_ci }; 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci enum EncodingMode { kRangeBasedEncoding, kReturnAddressBasedEncoding }; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Constructors for the various encodings. 551cb0ef41Sopenharmony_ci explicit HandlerTable(Code code); 561cb0ef41Sopenharmony_ci explicit HandlerTable(ByteArray byte_array); 571cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 581cb0ef41Sopenharmony_ci explicit HandlerTable(const wasm::WasmCode* code); 591cb0ef41Sopenharmony_ci#endif // V8_ENABLE_WEBASSEMBLY 601cb0ef41Sopenharmony_ci explicit HandlerTable(BytecodeArray bytecode_array); 611cb0ef41Sopenharmony_ci HandlerTable(Address handler_table, int handler_table_size, 621cb0ef41Sopenharmony_ci EncodingMode encoding_mode); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci // Getters for handler table based on ranges. 651cb0ef41Sopenharmony_ci int GetRangeStart(int index) const; 661cb0ef41Sopenharmony_ci int GetRangeEnd(int index) const; 671cb0ef41Sopenharmony_ci int GetRangeHandler(int index) const; 681cb0ef41Sopenharmony_ci int GetRangeData(int index) const; 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Setters for handler table based on ranges. 711cb0ef41Sopenharmony_ci void SetRangeStart(int index, int value); 721cb0ef41Sopenharmony_ci void SetRangeEnd(int index, int value); 731cb0ef41Sopenharmony_ci void SetRangeHandler(int index, int offset, CatchPrediction pred); 741cb0ef41Sopenharmony_ci void SetRangeData(int index, int value); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // Returns the required length of the underlying byte array. 771cb0ef41Sopenharmony_ci static int LengthForRange(int entries); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // Emitters for handler table based on return addresses. 801cb0ef41Sopenharmony_ci static int EmitReturnTableStart(Assembler* masm); 811cb0ef41Sopenharmony_ci static void EmitReturnEntry(Assembler* masm, int offset, int handler); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci // Lookup handler in a table based on ranges. The {pc_offset} is an offset to 841cb0ef41Sopenharmony_ci // the start of the potentially throwing instruction (using return addresses 851cb0ef41Sopenharmony_ci // for this value would be invalid). 861cb0ef41Sopenharmony_ci int LookupRange(int pc_offset, int* data, CatchPrediction* prediction); 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci // Lookup handler in a table based on return addresses. 891cb0ef41Sopenharmony_ci int LookupReturn(int pc_offset); 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci // Returns the number of entries in the table. 921cb0ef41Sopenharmony_ci int NumberOfRangeEntries() const; 931cb0ef41Sopenharmony_ci int NumberOfReturnEntries() const; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER 961cb0ef41Sopenharmony_ci void HandlerTableRangePrint(std::ostream& os); 971cb0ef41Sopenharmony_ci void HandlerTableReturnPrint(std::ostream& os); 981cb0ef41Sopenharmony_ci#endif 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci private: 1011cb0ef41Sopenharmony_ci // Getters for handler table based on ranges. 1021cb0ef41Sopenharmony_ci CatchPrediction GetRangePrediction(int index) const; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Gets entry size based on mode. 1051cb0ef41Sopenharmony_ci static int EntrySizeFromMode(EncodingMode mode); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci // Getters for handler table based on return addresses. 1081cb0ef41Sopenharmony_ci int GetReturnOffset(int index) const; 1091cb0ef41Sopenharmony_ci int GetReturnHandler(int index) const; 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci // Number of entries in the loaded handler table. 1121cb0ef41Sopenharmony_ci const int number_of_entries_; 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci#ifdef DEBUG 1151cb0ef41Sopenharmony_ci // The encoding mode of the table. Mostly useful for debugging to check that 1161cb0ef41Sopenharmony_ci // used accessors and constructors fit together. 1171cb0ef41Sopenharmony_ci const EncodingMode mode_; 1181cb0ef41Sopenharmony_ci#endif 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci // Direct pointer into the encoded data. This pointer potentially points into 1211cb0ef41Sopenharmony_ci // objects on the GC heap (either {ByteArray} or {Code}) and could become 1221cb0ef41Sopenharmony_ci // stale during a collection. Hence we disallow any allocation. 1231cb0ef41Sopenharmony_ci const Address raw_encoded_data_; 1241cb0ef41Sopenharmony_ci DISALLOW_GARBAGE_COLLECTION(no_gc_) 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci // Layout description for handler table based on ranges. 1271cb0ef41Sopenharmony_ci static const int kRangeStartIndex = 0; 1281cb0ef41Sopenharmony_ci static const int kRangeEndIndex = 1; 1291cb0ef41Sopenharmony_ci static const int kRangeHandlerIndex = 2; 1301cb0ef41Sopenharmony_ci static const int kRangeDataIndex = 3; 1311cb0ef41Sopenharmony_ci static const int kRangeEntrySize = 4; 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci // Layout description for handler table based on return addresses. 1341cb0ef41Sopenharmony_ci static const int kReturnOffsetIndex = 0; 1351cb0ef41Sopenharmony_ci static const int kReturnHandlerIndex = 1; 1361cb0ef41Sopenharmony_ci static const int kReturnEntrySize = 2; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci // Encoding of the {handler} field. 1391cb0ef41Sopenharmony_ci using HandlerPredictionField = base::BitField<CatchPrediction, 0, 3>; 1401cb0ef41Sopenharmony_ci using HandlerOffsetField = base::BitField<int, 3, 29>; 1411cb0ef41Sopenharmony_ci}; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci} // namespace internal 1441cb0ef41Sopenharmony_ci} // namespace v8 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_HANDLER_TABLE_H_ 147