Commit f35495ca authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[builtins] Reduce table size for bytecode mappings

This replaces kBytecodeToBuiltinsMapping (an array with currently 549
32-bit integers = 2196 bytes) with kWideBytecodeToBuiltinsMapping which
is an array of uint8_t with only 183 values. The new array contains just
the mappings from wide handlers to builtins but only once since the
mapping is the same for extra wide handlers. (No mapping array is
required for normal handlers since they map 1:1).

This reduces d8's binary size by 2008 bytes on x64.

As a result Interpreter::GetBytecodeHandler will be slightly slower than
before, but its only use in non-test code is in
Runtime_DebugBreakOnBytecode which does not need to be fast.

Bug: v8:11066
Change-Id: Iafc28fba2d1b62c1d49ceabe731d8b52a82dd2fd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2502291
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70836}
parent 90576e7f
...@@ -11,6 +11,9 @@ namespace v8 { ...@@ -11,6 +11,9 @@ namespace v8 {
namespace internal { namespace internal {
namespace interpreter { namespace interpreter {
const int kIllegalBytecodeHandler = -1;
const int kIllegalBytecodeHandlerEncoding = 255;
void WriteBytecode(std::ofstream& out, Bytecode bytecode, void WriteBytecode(std::ofstream& out, Bytecode bytecode,
OperandScale operand_scale, int* count, int offset_table[], OperandScale operand_scale, int* count, int offset_table[],
int table_index) { int table_index) {
...@@ -22,7 +25,7 @@ void WriteBytecode(std::ofstream& out, Bytecode bytecode, ...@@ -22,7 +25,7 @@ void WriteBytecode(std::ofstream& out, Bytecode bytecode,
offset_table[table_index] = *count; offset_table[table_index] = *count;
(*count)++; (*count)++;
} else { } else {
offset_table[table_index] = -1; offset_table[table_index] = kIllegalBytecodeHandler;
} }
} }
...@@ -32,6 +35,7 @@ void WriteHeader(const char* header_filename) { ...@@ -32,6 +35,7 @@ void WriteHeader(const char* header_filename) {
out << "// Automatically generated from interpreter/bytecodes.h\n" out << "// Automatically generated from interpreter/bytecodes.h\n"
<< "// The following list macro is used to populate the builtins list\n" << "// The following list macro is used to populate the builtins list\n"
<< "// with the bytecode handlers\n\n" << "// with the bytecode handlers\n\n"
<< "#include <stdint.h>\n\n"
<< "#ifndef V8_BUILTINS_GENERATED_BYTECODES_BUILTINS_LIST\n" << "#ifndef V8_BUILTINS_GENERATED_BYTECODES_BUILTINS_LIST\n"
<< "#define V8_BUILTINS_GENERATED_BYTECODES_BUILTINS_LIST\n\n" << "#define V8_BUILTINS_GENERATED_BYTECODES_BUILTINS_LIST\n\n"
<< "namespace v8 {\n" << "namespace v8 {\n"
...@@ -60,19 +64,25 @@ void WriteHeader(const char* header_filename) { ...@@ -60,19 +64,25 @@ void WriteHeader(const char* header_filename) {
CHECK_GT(single_count, wide_count); CHECK_GT(single_count, wide_count);
CHECK_EQ(single_count, Bytecodes::kBytecodeCount); CHECK_EQ(single_count, Bytecodes::kBytecodeCount);
CHECK_EQ(wide_count, extra_wide_count); CHECK_EQ(wide_count, extra_wide_count);
out << "\n\nconst int kNumberOfBytecodeHandlers = " << single_count << ";\n" out << "\n\nconstexpr int kNumberOfBytecodeHandlers = " << single_count
<< "const int kNumberOfWideBytecodeHandlers = " << wide_count << ";\n\n" << ";\n"
<< "// Mapping from (Bytecode + OperandScaleAsIndex * |Bytecodes|) to\n" << "constexpr int kNumberOfWideBytecodeHandlers = " << wide_count
<< "// a dense form with all the illegal Bytecode/OperandScale\n" << ";\n\n"
<< "// combinations removed. Used to index into the builtins table.\n" << "constexpr uint8_t kIllegalBytecodeHandlerEncoding = "
<< "constexpr int kBytecodeToBuiltinsMapping[" << kTableSize << "] = {\n" << kIllegalBytecodeHandlerEncoding << ";\n\n"
<< " "; << "// Mapping from Bytecode to a dense form with all the illegal\n"
<< "// wide Bytecodes removed. Used to index into the builtins table.\n"
<< "constexpr uint8_t kWideBytecodeToBuiltinsMapping["
<< "kNumberOfBytecodeHandlers] = { \n";
for (int i = 0; i < kTableSize; ++i) { for (int i = single_count; i < 2 * single_count; ++i) {
if (i == single_count || i == 2 * single_count) { int offset = offset_table[i];
out << "\n "; if (offset == kIllegalBytecodeHandler) {
offset = kIllegalBytecodeHandlerEncoding;
} else {
offset -= single_count;
} }
out << offset_table[i] << ", "; out << offset << ", ";
} }
out << "};\n\n" out << "};\n\n"
......
...@@ -78,12 +78,21 @@ Interpreter::Interpreter(Isolate* isolate) ...@@ -78,12 +78,21 @@ Interpreter::Interpreter(Isolate* isolate)
namespace { namespace {
int BuiltinIndexFromBytecode(Bytecode bytecode, OperandScale operand_scale) { int BuiltinIndexFromBytecode(Bytecode bytecode, OperandScale operand_scale) {
int index = BytecodeOperands::OperandScaleAsIndex(operand_scale) * int index = static_cast<int>(bytecode);
kNumberOfBytecodeHandlers + if (operand_scale != OperandScale::kSingle) {
static_cast<int>(bytecode); // The table contains uint8_t offsets starting at 0 with
int offset = kBytecodeToBuiltinsMapping[index]; // kIllegalBytecodeHandlerEncoding for illegal bytecode/scale combinations.
return offset >= 0 ? Builtins::kFirstBytecodeHandler + offset uint8_t offset = kWideBytecodeToBuiltinsMapping[index];
: Builtins::kIllegalHandler; if (offset == kIllegalBytecodeHandlerEncoding) {
return Builtins::kIllegalHandler;
} else {
index = kNumberOfBytecodeHandlers + offset;
if (operand_scale == OperandScale::kQuadruple) {
index += kNumberOfWideBytecodeHandlers;
}
}
}
return Builtins::kFirstBytecodeHandler + index;
} }
} // namespace } // namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment