Commit c626bc5e authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Reduce size of {WasmCode} objects

This is a first step to make {WasmCode} objects smaller. Many code
offsets are currently stored in {size_t} even though there were
originally (during assembly) an int. Others are stored in {uint32_t}.

This CL switches the function index and all code lengths and offsets to
int, because
a) bigger code is not supported anyway, and
b) the style guide recommends int over unsigned types.

This makes the {WasmCode} 24 bytes smaller on x64 (from 144 to 120
bytes).

R=ahaas@chromium.org

Bug: v8:10254
Change-Id: I8f78bf4be64d59cf9393e3b6662d9d3bd153d387
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2074217Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66462}
parent 6a2865d2
......@@ -68,7 +68,7 @@ struct WasmCompilationResult {
uint32_t tagged_parameter_slots = 0;
OwnedVector<byte> source_positions;
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions;
int func_index = static_cast<int>(kAnonymousFuncIndex);
int func_index = kAnonymousFuncIndex;
ExecutionTier requested_tier;
ExecutionTier result_tier;
Kind kind = kFunction;
......
......@@ -133,18 +133,18 @@ Address WasmCode::handler_table() const {
return instruction_start() + handler_table_offset_;
}
uint32_t WasmCode::handler_table_size() const {
int WasmCode::handler_table_size() const {
DCHECK_GE(constant_pool_offset_, handler_table_offset_);
return static_cast<uint32_t>(constant_pool_offset_ - handler_table_offset_);
return static_cast<int>(constant_pool_offset_ - handler_table_offset_);
}
Address WasmCode::code_comments() const {
return instruction_start() + code_comments_offset_;
}
uint32_t WasmCode::code_comments_size() const {
int WasmCode::code_comments_size() const {
DCHECK_GE(unpadded_binary_size_, code_comments_offset_);
return static_cast<uint32_t>(unpadded_binary_size_ - code_comments_offset_);
return static_cast<int>(unpadded_binary_size_ - code_comments_offset_);
}
void WasmCode::RegisterTrapHandlerData() {
......@@ -296,7 +296,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
<< unpadded_binary_size_ << " + " << padding << " padding)\n";
#ifdef ENABLE_DISASSEMBLER
size_t instruction_size = unpadded_binary_size_;
int instruction_size = unpadded_binary_size_;
if (constant_pool_offset_ < instruction_size) {
instruction_size = constant_pool_offset_;
}
......@@ -812,20 +812,16 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
Vector<const byte> instructions(
reinterpret_cast<byte*>(code->InstructionStart()),
static_cast<size_t>(code->InstructionSize()));
const uint32_t stack_slots = static_cast<uint32_t>(
code->has_safepoint_info() ? code->stack_slots() : 0);
const int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0;
// TODO(jgruber,v8:8758): Remove this translation. It exists only because
// Code objects contains real offsets but WasmCode expects an offset of 0 to
// mean 'empty'.
const size_t safepoint_table_offset = static_cast<size_t>(
code->has_safepoint_table() ? code->safepoint_table_offset() : 0);
const size_t handler_table_offset =
static_cast<size_t>(code->handler_table_offset());
const size_t constant_pool_offset =
static_cast<size_t>(code->constant_pool_offset());
const size_t code_comments_offset =
static_cast<size_t>(code->code_comments_offset());
const int safepoint_table_offset =
code->has_safepoint_table() ? code->safepoint_table_offset() : 0;
const int handler_table_offset = code->handler_table_offset();
const int constant_pool_offset = code->constant_pool_offset();
const int code_comments_offset = code->code_comments_offset();
Vector<uint8_t> dst_code_bytes =
code_allocator_.AllocateForCode(this, instructions.size());
......@@ -869,7 +865,7 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
handler_table_offset, // handler_table_offset
constant_pool_offset, // constant_pool_offset
code_comments_offset, // code_comments_offset
instructions.size(), // unpadded_binary_size
instructions.length(), // unpadded_binary_size
OwnedVector<ProtectedInstructionData>{}, // protected_instructions
std::move(reloc_info), // reloc_info
std::move(source_pos), // source positions
......@@ -917,8 +913,8 @@ void NativeModule::UseLazyStub(uint32_t func_index) {
}
std::unique_ptr<WasmCode> NativeModule::AddCode(
uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
uint32_t tagged_parameter_slots,
int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots,
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier) {
......@@ -933,8 +929,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCode(
}
std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
uint32_t tagged_parameter_slots,
int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots,
OwnedVector<ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier, Vector<uint8_t> dst_code_bytes,
......@@ -949,15 +945,12 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
// TODO(jgruber,v8:8758): Remove this translation. It exists only because
// CodeDesc contains real offsets but WasmCode expects an offset of 0 to mean
// 'empty'.
const size_t safepoint_table_offset = static_cast<size_t>(
desc.safepoint_table_size == 0 ? 0 : desc.safepoint_table_offset);
const size_t handler_table_offset =
static_cast<size_t>(desc.handler_table_offset);
const size_t constant_pool_offset =
static_cast<size_t>(desc.constant_pool_offset);
const size_t code_comments_offset =
static_cast<size_t>(desc.code_comments_offset);
const size_t instr_size = static_cast<size_t>(desc.instr_size);
const int safepoint_table_offset =
desc.safepoint_table_size == 0 ? 0 : desc.safepoint_table_offset;
const int handler_table_offset = desc.handler_table_offset;
const int constant_pool_offset = desc.constant_pool_offset;
const int code_comments_offset = desc.code_comments_offset;
const int instr_size = desc.instr_size;
memcpy(dst_code_bytes.begin(), desc.buffer,
static_cast<size_t>(desc.instr_size));
......@@ -1080,10 +1073,10 @@ WasmCode* NativeModule::PublishCodeLocked(std::unique_ptr<WasmCode> code) {
}
WasmCode* NativeModule::AddDeserializedCode(
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
uint32_t tagged_parameter_slots, size_t safepoint_table_offset,
size_t handler_table_offset, size_t constant_pool_offset,
size_t code_comments_offset, size_t unpadded_binary_size,
int index, Vector<const byte> instructions, int stack_slots,
int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset,
int code_comments_offset, int unpadded_binary_size,
OwnedVector<ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
......@@ -1140,7 +1133,7 @@ WasmModuleSourceMap* NativeModule::GetWasmSourceMap() const {
}
WasmCode* NativeModule::CreateEmptyJumpTableInRegion(
uint32_t jump_table_size, base::AddressRegion region,
int jump_table_size, base::AddressRegion region,
const WasmCodeAllocator::OptionalLock& allocator_lock) {
// Only call this if we really need a jump table.
DCHECK_LT(0, jump_table_size);
......
......@@ -130,8 +130,9 @@ class V8_EXPORT_PRIVATE WasmCode final {
return source_position_table_.as_vector();
}
// TODO(clemensb): Make this return int.
uint32_t index() const {
DCHECK(!IsAnonymous());
DCHECK_LE(0, index_);
return index_;
}
// Anonymous functions are functions that don't carry an index.
......@@ -141,16 +142,16 @@ class V8_EXPORT_PRIVATE WasmCode final {
ExecutionTier tier() const { return tier_; }
Address constant_pool() const;
Address handler_table() const;
uint32_t handler_table_size() const;
int handler_table_size() const;
Address code_comments() const;
uint32_t code_comments_size() const;
size_t constant_pool_offset() const { return constant_pool_offset_; }
size_t safepoint_table_offset() const { return safepoint_table_offset_; }
size_t handler_table_offset() const { return handler_table_offset_; }
size_t code_comments_offset() const { return code_comments_offset_; }
size_t unpadded_binary_size() const { return unpadded_binary_size_; }
uint32_t stack_slots() const { return stack_slots_; }
uint32_t tagged_parameter_slots() const { return tagged_parameter_slots_; }
int code_comments_size() const;
int constant_pool_offset() const { return constant_pool_offset_; }
int safepoint_table_offset() const { return safepoint_table_offset_; }
int handler_table_offset() const { return handler_table_offset_; }
int code_comments_offset() const { return code_comments_offset_; }
int unpadded_binary_size() const { return unpadded_binary_size_; }
int stack_slots() const { return stack_slots_; }
int tagged_parameter_slots() const { return tagged_parameter_slots_; }
bool is_liftoff() const { return tier_ == ExecutionTier::kLiftoff; }
bool contains(Address pc) const {
return reinterpret_cast<Address>(instructions_.begin()) <= pc &&
......@@ -207,16 +208,14 @@ class V8_EXPORT_PRIVATE WasmCode final {
enum FlushICache : bool { kFlushICache = true, kNoFlushICache = false };
STATIC_ASSERT(kAnonymousFuncIndex > kV8MaxWasmFunctions);
private:
friend class NativeModule;
WasmCode(NativeModule* native_module, uint32_t index,
Vector<byte> instructions, uint32_t stack_slots,
uint32_t tagged_parameter_slots, size_t safepoint_table_offset,
size_t handler_table_offset, size_t constant_pool_offset,
size_t code_comments_offset, size_t unpadded_binary_size,
WasmCode(NativeModule* native_module, int index, Vector<byte> instructions,
int stack_slots, int tagged_parameter_slots,
int safepoint_table_offset, int handler_table_offset,
int constant_pool_offset, int code_comments_offset,
int unpadded_binary_size,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<const byte> reloc_info,
......@@ -267,20 +266,19 @@ class V8_EXPORT_PRIVATE WasmCode final {
OwnedVector<const byte> reloc_info_;
OwnedVector<const byte> source_position_table_;
NativeModule* native_module_ = nullptr;
uint32_t index_;
int index_;
Kind kind_;
size_t constant_pool_offset_ = 0;
uint32_t stack_slots_ = 0;
int constant_pool_offset_ = 0;
int stack_slots_ = 0;
// Number of tagged parameters passed to this function via the stack. This
// value is used by the stack walker (e.g. GC) to find references.
uint32_t tagged_parameter_slots_ = 0;
// we care about safepoint data for wasm-to-js functions,
// since there may be stack/register tagged values for large number
// conversions.
size_t safepoint_table_offset_ = 0;
size_t handler_table_offset_ = 0;
size_t code_comments_offset_ = 0;
size_t unpadded_binary_size_ = 0;
int tagged_parameter_slots_ = 0;
// We care about safepoint data for wasm-to-js functions, since there may be
// stack/register tagged values for large number conversions.
int safepoint_table_offset_ = 0;
int handler_table_offset_ = 0;
int code_comments_offset_ = 0;
int unpadded_binary_size_ = 0;
int trap_handler_index_ = -1;
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions_;
ExecutionTier tier_;
......@@ -300,6 +298,12 @@ class V8_EXPORT_PRIVATE WasmCode final {
DISALLOW_COPY_AND_ASSIGN(WasmCode);
};
// Check that {WasmCode} objects are sufficiently small. We create many of them,
// often for rather small functions.
// Increase the limit if needed, but first check if the size increase is
// justified.
STATIC_ASSERT(sizeof(WasmCode) <= 120);
WasmCode::Kind GetCodeKind(const WasmCompilationResult& result);
// Return a textual description of the kind.
......@@ -406,8 +410,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
// code below, i.e. it can be called concurrently from background threads.
// The returned code still needs to be published via {PublishCode}.
std::unique_ptr<WasmCode> AddCode(
uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
uint32_t tagged_parameter_slots,
int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
......@@ -421,10 +425,10 @@ class V8_EXPORT_PRIVATE NativeModule final {
WasmCode* PublishCodeLocked(std::unique_ptr<WasmCode>);
WasmCode* AddDeserializedCode(
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
uint32_t tagged_parameter_slots, size_t safepoint_table_offset,
size_t handler_table_offset, size_t constant_pool_offset,
size_t code_comments_offset, size_t unpadded_binary_size,
int index, Vector<const byte> instructions, int stack_slots,
int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset,
int code_comments_offset, int unpadded_binary_size,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<const byte> reloc_info,
......@@ -593,8 +597,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
std::shared_ptr<NativeModule>* shared_this);
std::unique_ptr<WasmCode> AddCodeWithCodeSpace(
uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
uint32_t tagged_parameter_slots,
int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
......@@ -602,7 +606,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
const JumpTablesRef& jump_tables_ref);
WasmCode* CreateEmptyJumpTableInRegion(
uint32_t jump_table_size, base::AddressRegion,
int jump_table_size, base::AddressRegion,
const WasmCodeAllocator::OptionalLock&);
// Hold the {allocation_mutex_} when calling one of these methods.
......
......@@ -108,7 +108,7 @@ constexpr WasmCodePosition kNoCodePosition = -1;
constexpr uint32_t kExceptionAttribute = 0;
constexpr uint32_t kAnonymousFuncIndex = 0xffffffff;
constexpr int kAnonymousFuncIndex = -1;
} // namespace wasm
} // namespace internal
......
......@@ -188,19 +188,18 @@ constexpr size_t kHeaderSize =
sizeof(uint32_t) + // total wasm function count
sizeof(uint32_t); // imported functions (index of first wasm function)
constexpr size_t kCodeHeaderSize =
sizeof(size_t) + // size of code section
sizeof(size_t) + // offset of constant pool
sizeof(size_t) + // offset of safepoint table
sizeof(size_t) + // offset of handler table
sizeof(size_t) + // offset of code comments
sizeof(size_t) + // unpadded binary size
sizeof(uint32_t) + // stack slots
sizeof(uint32_t) + // tagged parameter slots
sizeof(size_t) + // code size
sizeof(size_t) + // reloc size
sizeof(size_t) + // source positions size
sizeof(size_t) + // protected instructions size
constexpr size_t kCodeHeaderSize = sizeof(bool) + // whether code is present
sizeof(int) + // offset of constant pool
sizeof(int) + // offset of safepoint table
sizeof(int) + // offset of handler table
sizeof(int) + // offset of code comments
sizeof(int) + // unpadded binary size
sizeof(int) + // stack slots
sizeof(int) + // tagged parameter slots
sizeof(int) + // code size
sizeof(int) + // reloc size
sizeof(int) + // source positions size
sizeof(int) + // protected instructions size
sizeof(WasmCode::Kind) + // code kind
sizeof(ExecutionTier); // tier
......@@ -300,7 +299,7 @@ NativeModuleSerializer::NativeModuleSerializer(
}
size_t NativeModuleSerializer::MeasureCode(const WasmCode* code) const {
if (code == nullptr) return sizeof(size_t);
if (code == nullptr) return sizeof(bool);
DCHECK(code->kind() == WasmCode::kFunction ||
code->kind() == WasmCode::kInterpreterEntry);
return kCodeHeaderSize + code->instructions().size() +
......@@ -327,13 +326,13 @@ void NativeModuleSerializer::WriteHeader(Writer* writer) {
void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
if (code == nullptr) {
writer->Write(size_t{0});
writer->Write(false);
return;
}
writer->Write(true);
DCHECK(code->kind() == WasmCode::kFunction ||
code->kind() == WasmCode::kInterpreterEntry);
// Write the size of the entire code section, followed by the code header.
writer->Write(MeasureCode(code));
writer->Write(code->constant_pool_offset());
writer->Write(code->safepoint_table_offset());
writer->Write(code->handler_table_offset());
......@@ -341,10 +340,10 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
writer->Write(code->unpadded_binary_size());
writer->Write(code->stack_slots());
writer->Write(code->tagged_parameter_slots());
writer->Write(code->instructions().size());
writer->Write(code->reloc_info().size());
writer->Write(code->source_positions().size());
writer->Write(code->protected_instructions().size());
writer->Write(code->instructions().length());
writer->Write(code->reloc_info().length());
writer->Write(code->source_positions().length());
writer->Write(code->protected_instructions().length());
writer->Write(code->kind());
writer->Write(code->tier());
......@@ -462,7 +461,7 @@ class V8_EXPORT_PRIVATE NativeModuleDeserializer {
private:
bool ReadHeader(Reader* reader);
bool ReadCode(uint32_t fn_index, Reader* reader);
bool ReadCode(int fn_index, Reader* reader);
NativeModule* const native_module_;
bool read_called_;
......@@ -493,29 +492,30 @@ bool NativeModuleDeserializer::ReadHeader(Reader* reader) {
imports == native_module_->num_imported_functions();
}
bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
size_t code_section_size = reader->Read<size_t>();
if (code_section_size == 0) {
bool NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
bool has_code = reader->Read<bool>();
if (!has_code) {
DCHECK(FLAG_wasm_lazy_compilation ||
native_module_->enabled_features().has_compilation_hints());
native_module_->UseLazyStub(fn_index);
return true;
}
size_t constant_pool_offset = reader->Read<size_t>();
size_t safepoint_table_offset = reader->Read<size_t>();
size_t handler_table_offset = reader->Read<size_t>();
size_t code_comment_offset = reader->Read<size_t>();
size_t unpadded_binary_size = reader->Read<size_t>();
uint32_t stack_slot_count = reader->Read<uint32_t>();
uint32_t tagged_parameter_slots = reader->Read<uint32_t>();
size_t code_size = reader->Read<size_t>();
size_t reloc_size = reader->Read<size_t>();
size_t source_position_size = reader->Read<size_t>();
size_t protected_instructions_size = reader->Read<size_t>();
int constant_pool_offset = reader->Read<int>();
int safepoint_table_offset = reader->Read<int>();
int handler_table_offset = reader->Read<int>();
int code_comment_offset = reader->Read<int>();
int unpadded_binary_size = reader->Read<int>();
int stack_slot_count = reader->Read<int>();
int tagged_parameter_slots = reader->Read<int>();
int code_size = reader->Read<int>();
int reloc_size = reader->Read<int>();
int source_position_size = reader->Read<int>();
int protected_instructions_size = reader->Read<int>();
WasmCode::Kind kind = reader->Read<WasmCode::Kind>();
ExecutionTier tier = reader->Read<ExecutionTier>();
Vector<const byte> code_buffer = {reader->current_location(), code_size};
Vector<const byte> code_buffer{reader->current_location(),
static_cast<size_t>(code_size)};
reader->Skip(code_size);
OwnedVector<byte> reloc_info = OwnedVector<byte>::New(reloc_size);
......
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