Commit 28afd1c9 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

Revert "[wasm] Further reduce the size of WasmCode"

This reverts commit 79398ab0.

Reason for revert: Makes UBSan unhappy: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux64%20UBSan/10186

Original change's description:
> [wasm] Further reduce the size of WasmCode
> 
> Also, save dynamic allocations (plus their memory overhead).
> This is realized by storing the relocation information, source position
> table, and protected instruction information together in one "metadata"
> byte array.
> For each of the three components, we just store their size, such that
> the accessors can return the respecitive {Vector} views as before.
> 
> This makes each WasmCode object 24 bytes smaller on 64-bit
> architectures. It also saves a few more bytes per code object because
> less padding is needed for the individual allocations, and each dynamic
> allocation comes with some constant memory overhead.
> 
> Since the protected instructions will just be stored in a byte array
> now, some APIs are refactored to just return that byte array directly
> (instead of an array of {ProtectedInstructionData}). This also
> simplifies serialization and deserialization, and will allow for
> switching to a more compact representation in the future.
> 
> Drive-by: Add some more checks to {Vector::cast} to protect against
>   undefined behaviour.
> 
> R=​ahaas@chromium.org
> 
> Bug: v8:10254
> Change-Id: I81ca847023841110e3e52cc402fcb0349325d7af
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2078545
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Commit-Queue: Clemens Backes <clemensb@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#66596}

TBR=jkummerow@chromium.org,ahaas@chromium.org,clemensb@chromium.org,tebbi@chromium.org

Change-Id: Id80aa82cfce8942879031032b322ee66855b5600
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:10254
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2089933Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66597}
parent 79398ab0
...@@ -432,9 +432,10 @@ OwnedVector<byte> CodeGenerator::GetSourcePositionTable() { ...@@ -432,9 +432,10 @@ OwnedVector<byte> CodeGenerator::GetSourcePositionTable() {
return source_position_table_builder_.ToSourcePositionTableVector(); return source_position_table_builder_.ToSourcePositionTableVector();
} }
OwnedVector<byte> CodeGenerator::GetProtectedInstructionsData() { OwnedVector<trap_handler::ProtectedInstructionData>
return OwnedVector<byte>::Of( CodeGenerator::GetProtectedInstructions() {
Vector<byte>::cast(VectorOf(protected_instructions_))); return OwnedVector<trap_handler::ProtectedInstructionData>::Of(
protected_instructions_);
} }
MaybeHandle<Code> CodeGenerator::FinalizeCode() { MaybeHandle<Code> CodeGenerator::FinalizeCode() {
......
...@@ -125,7 +125,8 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler { ...@@ -125,7 +125,8 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
MaybeHandle<Code> FinalizeCode(); MaybeHandle<Code> FinalizeCode();
OwnedVector<byte> GetSourcePositionTable(); OwnedVector<byte> GetSourcePositionTable();
OwnedVector<byte> GetProtectedInstructionsData(); OwnedVector<trap_handler::ProtectedInstructionData>
GetProtectedInstructions();
InstructionSequence* instructions() const { return instructions_; } InstructionSequence* instructions() const { return instructions_; }
FrameAccessState* frame_access_state() const { return frame_access_state_; } FrameAccessState* frame_access_state() const { return frame_access_state_; }
......
...@@ -2765,8 +2765,7 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub( ...@@ -2765,8 +2765,7 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
static_cast<int>(code_generator->GetHandlerTableOffset())); static_cast<int>(code_generator->GetHandlerTableOffset()));
result.instr_buffer = instruction_buffer->ReleaseBuffer(); result.instr_buffer = instruction_buffer->ReleaseBuffer();
result.source_positions = code_generator->GetSourcePositionTable(); result.source_positions = code_generator->GetSourcePositionTable();
result.protected_instructions_data = result.protected_instructions = code_generator->GetProtectedInstructions();
code_generator->GetProtectedInstructionsData();
result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount(); result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.result_tier = wasm::ExecutionTier::kTurbofan; result.result_tier = wasm::ExecutionTier::kTurbofan;
...@@ -2973,8 +2972,7 @@ void Pipeline::GenerateCodeForWasmFunction( ...@@ -2973,8 +2972,7 @@ void Pipeline::GenerateCodeForWasmFunction(
result->frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount(); result->frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result->source_positions = code_generator->GetSourcePositionTable(); result->source_positions = code_generator->GetSourcePositionTable();
result->protected_instructions_data = result->protected_instructions = code_generator->GetProtectedInstructions();
code_generator->GetProtectedInstructionsData();
result->result_tier = wasm::ExecutionTier::kTurbofan; result->result_tier = wasm::ExecutionTier::kTurbofan;
if (data.info()->trace_turbo_json_enabled()) { if (data.info()->trace_turbo_json_enabled()) {
......
...@@ -6666,9 +6666,8 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine, ...@@ -6666,9 +6666,8 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
WasmStubAssemblerOptions(), source_positions); WasmStubAssemblerOptions(), source_positions);
std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode( std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
wasm::kAnonymousFuncIndex, result.code_desc, result.frame_slot_count, wasm::kAnonymousFuncIndex, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), wasm::WasmCode::kWasmToCapiWrapper,
result.source_positions.as_vector(), wasm::WasmCode::kWasmToCapiWrapper,
wasm::ExecutionTier::kNone); wasm::ExecutionTier::kNone);
return native_module->PublishCode(std::move(wasm_code)); return native_module->PublishCode(std::move(wasm_code));
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <cstring> #include <cstring>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <type_traits>
#include "src/common/checks.h" #include "src/common/checks.h"
#include "src/common/globals.h" #include "src/common/globals.h"
...@@ -117,14 +116,6 @@ class Vector { ...@@ -117,14 +116,6 @@ class Vector {
template <typename S> template <typename S>
static constexpr Vector<T> cast(Vector<S> input) { static constexpr Vector<T> cast(Vector<S> input) {
// Casting is potentially dangerous, so be really restrictive here. This
// might be lifted once we have use cases for that.
STATIC_ASSERT(std::is_pod<S>::value);
STATIC_ASSERT(std::is_pod<T>::value);
#if V8_HAS_CXX14_CONSTEXPR
DCHECK_EQ(0, (input.length() * sizeof(S)) % sizeof(T));
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(input.begin()) % alignof(T));
#endif
return Vector<T>(reinterpret_cast<T*>(input.begin()), return Vector<T>(reinterpret_cast<T*>(input.begin()),
input.length() * sizeof(S) / sizeof(T)); input.length() * sizeof(S) / sizeof(T));
} }
......
...@@ -321,9 +321,10 @@ class LiftoffCompiler { ...@@ -321,9 +321,10 @@ class LiftoffCompiler {
return source_position_table_builder_.ToSourcePositionTableVector(); return source_position_table_builder_.ToSourcePositionTableVector();
} }
OwnedVector<uint8_t> GetProtectedInstructionsData() const { OwnedVector<trap_handler::ProtectedInstructionData> GetProtectedInstructions()
return OwnedVector<uint8_t>::Of( const {
Vector<const uint8_t>::cast(VectorOf(protected_instructions_))); return OwnedVector<trap_handler::ProtectedInstructionData>::Of(
protected_instructions_);
} }
uint32_t GetTotalFrameSlotCount() const { uint32_t GetTotalFrameSlotCount() const {
...@@ -2795,7 +2796,7 @@ WasmCompilationResult ExecuteLiftoffCompilation( ...@@ -2795,7 +2796,7 @@ WasmCompilationResult ExecuteLiftoffCompilation(
compiler->GetCode(&result.code_desc); compiler->GetCode(&result.code_desc);
result.instr_buffer = instruction_buffer->ReleaseBuffer(); result.instr_buffer = instruction_buffer->ReleaseBuffer();
result.source_positions = compiler->GetSourcePositionTable(); result.source_positions = compiler->GetSourcePositionTable();
result.protected_instructions_data = compiler->GetProtectedInstructionsData(); result.protected_instructions = compiler->GetProtectedInstructions();
result.frame_slot_count = compiler->GetTotalFrameSlotCount(); result.frame_slot_count = compiler->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.func_index = func_index; result.func_index = func_index;
......
...@@ -67,7 +67,7 @@ struct WasmCompilationResult { ...@@ -67,7 +67,7 @@ struct WasmCompilationResult {
uint32_t frame_slot_count = 0; uint32_t frame_slot_count = 0;
uint32_t tagged_parameter_slots = 0; uint32_t tagged_parameter_slots = 0;
OwnedVector<byte> source_positions; OwnedVector<byte> source_positions;
OwnedVector<byte> protected_instructions_data; OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions;
int func_index = kAnonymousFuncIndex; int func_index = kAnonymousFuncIndex;
ExecutionTier requested_tier; ExecutionTier requested_tier;
ExecutionTier result_tier; ExecutionTier result_tier;
......
...@@ -2972,9 +2972,8 @@ WasmCode* CompileImportWrapper( ...@@ -2972,9 +2972,8 @@ WasmCode* CompileImportWrapper(
wasm_engine, &env, kind, sig, source_positions); wasm_engine, &env, kind, sig, source_positions);
std::unique_ptr<WasmCode> wasm_code = native_module->AddCode( std::unique_ptr<WasmCode> wasm_code = native_module->AddCode(
result.func_index, result.code_desc, result.frame_slot_count, result.func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), GetCodeKind(result),
result.source_positions.as_vector(), GetCodeKind(result),
ExecutionTier::kNone); ExecutionTier::kNone);
WasmCode* published_code = native_module->PublishCode(std::move(wasm_code)); WasmCode* published_code = native_module->PublishCode(std::move(wasm_code));
(*cache_scope)[key] = published_code; (*cache_scope)[key] = published_code;
......
...@@ -147,32 +147,17 @@ int WasmCode::code_comments_size() const { ...@@ -147,32 +147,17 @@ int WasmCode::code_comments_size() const {
return static_cast<int>(unpadded_binary_size_ - code_comments_offset_); return static_cast<int>(unpadded_binary_size_ - code_comments_offset_);
} }
std::unique_ptr<const byte[]> WasmCode::ConcatenateBytes(
std::initializer_list<Vector<const byte>> vectors) {
size_t total_size = 0;
for (auto& vec : vectors) total_size += vec.size();
// Use default-initialization (== no initialization).
std::unique_ptr<byte[]> result{new byte[total_size]};
byte* ptr = result.get();
for (auto& vec : vectors) {
memcpy(ptr, vec.begin(), vec.size());
ptr += vec.size();
}
return result;
}
void WasmCode::RegisterTrapHandlerData() { void WasmCode::RegisterTrapHandlerData() {
DCHECK(!has_trap_handler_index()); DCHECK(!has_trap_handler_index());
if (kind() != WasmCode::kFunction) return; if (kind() != WasmCode::kFunction) return;
if (protected_instructions_size_ == 0) return; if (protected_instructions_.empty()) return;
Address base = instruction_start(); Address base = instruction_start();
size_t size = instructions().size(); size_t size = instructions().size();
auto protected_instruction_data = this->protected_instructions();
const int index = const int index =
RegisterHandlerData(base, size, protected_instruction_data.size(), RegisterHandlerData(base, size, protected_instructions().size(),
protected_instruction_data.begin()); protected_instructions().begin());
// TODO(eholk): if index is negative, fail. // TODO(eholk): if index is negative, fail.
CHECK_LE(0, index); CHECK_LE(0, index);
...@@ -337,7 +322,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os, ...@@ -337,7 +322,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
os << "\n"; os << "\n";
} }
if (protected_instructions_size_ > 0) { if (!protected_instructions_.empty()) {
os << "Protected instructions:\n pc offset land pad\n"; os << "Protected instructions:\n pc offset land pad\n";
for (auto& data : protected_instructions()) { for (auto& data : protected_instructions()) {
os << std::setw(10) << std::hex << data.instr_offset << std::setw(10) os << std::setw(10) << std::hex << data.instr_offset << std::setw(10)
...@@ -379,7 +364,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os, ...@@ -379,7 +364,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
os << "\n"; os << "\n";
} }
os << "RelocInfo (size = " << reloc_info().size() << ")\n"; os << "RelocInfo (size = " << reloc_info_.size() << ")\n";
for (RelocIterator it(instructions(), reloc_info(), constant_pool()); for (RelocIterator it(instructions(), reloc_info(), constant_pool());
!it.done(); it.next()) { !it.done(); it.next()) {
it.rinfo()->Print(nullptr, os); it.rinfo()->Print(nullptr, os);
...@@ -870,22 +855,22 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) { ...@@ -870,22 +855,22 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
// Flush the i-cache after relocation. // Flush the i-cache after relocation.
FlushInstructionCache(dst_code_bytes.begin(), dst_code_bytes.size()); FlushInstructionCache(dst_code_bytes.begin(), dst_code_bytes.size());
std::unique_ptr<WasmCode> new_code{ std::unique_ptr<WasmCode> new_code{new WasmCode{
new WasmCode{this, // native_module this, // native_module
kAnonymousFuncIndex, // index kAnonymousFuncIndex, // index
dst_code_bytes, // instructions dst_code_bytes, // instructions
stack_slots, // stack_slots stack_slots, // stack_slots
0, // tagged_parameter_slots 0, // tagged_parameter_slots
safepoint_table_offset, // safepoint_table_offset safepoint_table_offset, // safepoint_table_offset
handler_table_offset, // handler_table_offset handler_table_offset, // handler_table_offset
constant_pool_offset, // constant_pool_offset constant_pool_offset, // constant_pool_offset
code_comments_offset, // code_comments_offset code_comments_offset, // code_comments_offset
instructions.length(), // unpadded_binary_size instructions.length(), // unpadded_binary_size
{}, // protected_instructions OwnedVector<ProtectedInstructionData>{}, // protected_instructions
reloc_info.as_vector(), // reloc_info std::move(reloc_info), // reloc_info
source_pos.as_vector(), // source positions std::move(source_pos), // source positions
WasmCode::kFunction, // kind WasmCode::kFunction, // kind
ExecutionTier::kNone}}; // tier ExecutionTier::kNone}}; // tier
new_code->MaybePrint(nullptr); new_code->MaybePrint(nullptr);
new_code->Validate(); new_code->Validate();
...@@ -929,27 +914,33 @@ void NativeModule::UseLazyStub(uint32_t func_index) { ...@@ -929,27 +914,33 @@ void NativeModule::UseLazyStub(uint32_t func_index) {
std::unique_ptr<WasmCode> NativeModule::AddCode( std::unique_ptr<WasmCode> NativeModule::AddCode(
int index, const CodeDesc& desc, int stack_slots, int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots, Vector<const byte> protected_instructions_data, int tagged_parameter_slots,
Vector<const byte> source_position_table, WasmCode::Kind kind, OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier) { ExecutionTier tier) {
Vector<byte> code_space = Vector<byte> code_space =
code_allocator_.AllocateForCode(this, desc.instr_size); code_allocator_.AllocateForCode(this, desc.instr_size);
auto jump_table_ref = auto jump_table_ref =
FindJumpTablesForRegion(base::AddressRegionOf(code_space)); FindJumpTablesForRegion(base::AddressRegionOf(code_space));
return AddCodeWithCodeSpace(index, desc, stack_slots, tagged_parameter_slots, return AddCodeWithCodeSpace(index, desc, stack_slots, tagged_parameter_slots,
protected_instructions_data, std::move(protected_instructions),
source_position_table, kind, tier, code_space, std::move(source_position_table), kind, tier,
jump_table_ref); code_space, jump_table_ref);
} }
std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
int index, const CodeDesc& desc, int stack_slots, int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots, Vector<const byte> protected_instructions_data, int tagged_parameter_slots,
Vector<const byte> source_position_table, WasmCode::Kind kind, OwnedVector<ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier, Vector<uint8_t> dst_code_bytes, ExecutionTier tier, Vector<uint8_t> dst_code_bytes,
const JumpTablesRef& jump_tables) { const JumpTablesRef& jump_tables) {
Vector<byte> reloc_info{desc.buffer + desc.buffer_size - desc.reloc_size, OwnedVector<byte> reloc_info;
static_cast<size_t>(desc.reloc_size)}; if (desc.reloc_size > 0) {
reloc_info = OwnedVector<byte>::New(desc.reloc_size);
memcpy(reloc_info.start(), desc.buffer + desc.buffer_size - desc.reloc_size,
desc.reloc_size);
}
// TODO(jgruber,v8:8758): Remove this translation. It exists only because // TODO(jgruber,v8:8758): Remove this translation. It exists only because
// CodeDesc contains real offsets but WasmCode expects an offset of 0 to mean // CodeDesc contains real offsets but WasmCode expects an offset of 0 to mean
...@@ -971,8 +962,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( ...@@ -971,8 +962,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL); RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL);
Address code_start = reinterpret_cast<Address>(dst_code_bytes.begin()); Address code_start = reinterpret_cast<Address>(dst_code_bytes.begin());
Address constant_pool_start = code_start + constant_pool_offset; Address constant_pool_start = code_start + constant_pool_offset;
for (RelocIterator it(dst_code_bytes, reloc_info, constant_pool_start, for (RelocIterator it(dst_code_bytes, reloc_info.as_vector(),
mode_mask); constant_pool_start, mode_mask);
!it.done(); it.next()) { !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (RelocInfo::IsWasmCall(mode)) { if (RelocInfo::IsWasmCall(mode)) {
...@@ -996,8 +987,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( ...@@ -996,8 +987,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
std::unique_ptr<WasmCode> code{new WasmCode{ std::unique_ptr<WasmCode> code{new WasmCode{
this, index, dst_code_bytes, stack_slots, tagged_parameter_slots, this, index, dst_code_bytes, stack_slots, tagged_parameter_slots,
safepoint_table_offset, handler_table_offset, constant_pool_offset, safepoint_table_offset, handler_table_offset, constant_pool_offset,
code_comments_offset, instr_size, protected_instructions_data, reloc_info, code_comments_offset, instr_size, std::move(protected_instructions),
source_position_table, kind, tier}}; std::move(reloc_info), std::move(source_position_table), kind, tier}};
code->MaybePrint(); code->MaybePrint();
code->Validate(); code->Validate();
...@@ -1086,9 +1077,10 @@ WasmCode* NativeModule::AddDeserializedCode( ...@@ -1086,9 +1077,10 @@ WasmCode* NativeModule::AddDeserializedCode(
int tagged_parameter_slots, int safepoint_table_offset, int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset, int handler_table_offset, int constant_pool_offset,
int code_comments_offset, int unpadded_binary_size, int code_comments_offset, int unpadded_binary_size,
Vector<const byte> protected_instructions_data, OwnedVector<ProtectedInstructionData> protected_instructions,
Vector<const byte> reloc_info, Vector<const byte> source_position_table, OwnedVector<const byte> reloc_info,
WasmCode::Kind kind, ExecutionTier tier) { OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier) {
Vector<uint8_t> dst_code_bytes = Vector<uint8_t> dst_code_bytes =
code_allocator_.AllocateForCode(this, instructions.size()); code_allocator_.AllocateForCode(this, instructions.size());
memcpy(dst_code_bytes.begin(), instructions.begin(), instructions.size()); memcpy(dst_code_bytes.begin(), instructions.begin(), instructions.size());
...@@ -1096,8 +1088,9 @@ WasmCode* NativeModule::AddDeserializedCode( ...@@ -1096,8 +1088,9 @@ WasmCode* NativeModule::AddDeserializedCode(
std::unique_ptr<WasmCode> code{new WasmCode{ std::unique_ptr<WasmCode> code{new WasmCode{
this, index, dst_code_bytes, stack_slots, tagged_parameter_slots, this, index, dst_code_bytes, stack_slots, tagged_parameter_slots,
safepoint_table_offset, handler_table_offset, constant_pool_offset, safepoint_table_offset, handler_table_offset, constant_pool_offset,
code_comments_offset, unpadded_binary_size, protected_instructions_data, code_comments_offset, unpadded_binary_size,
reloc_info, source_position_table, kind, tier}}; std::move(protected_instructions), std::move(reloc_info),
std::move(source_position_table), kind, tier}};
// Note: we do not flush the i-cache here, since the code needs to be // Note: we do not flush the i-cache here, since the code needs to be
// relocated anyway. The caller is responsible for flushing the i-cache later. // relocated anyway. The caller is responsible for flushing the i-cache later.
...@@ -1148,22 +1141,22 @@ WasmCode* NativeModule::CreateEmptyJumpTableInRegion( ...@@ -1148,22 +1141,22 @@ WasmCode* NativeModule::CreateEmptyJumpTableInRegion(
this, jump_table_size, region, allocator_lock); this, jump_table_size, region, allocator_lock);
DCHECK(!code_space.empty()); DCHECK(!code_space.empty());
ZapCode(reinterpret_cast<Address>(code_space.begin()), code_space.size()); ZapCode(reinterpret_cast<Address>(code_space.begin()), code_space.size());
std::unique_ptr<WasmCode> code{ std::unique_ptr<WasmCode> code{new WasmCode{
new WasmCode{this, // native_module this, // native_module
kAnonymousFuncIndex, // index kAnonymousFuncIndex, // index
code_space, // instructions code_space, // instructions
0, // stack_slots 0, // stack_slots
0, // tagged_parameter_slots 0, // tagged_parameter_slots
0, // safepoint_table_offset 0, // safepoint_table_offset
jump_table_size, // handler_table_offset jump_table_size, // handler_table_offset
jump_table_size, // constant_pool_offset jump_table_size, // constant_pool_offset
jump_table_size, // code_comments_offset jump_table_size, // code_comments_offset
jump_table_size, // unpadded_binary_size jump_table_size, // unpadded_binary_size
{}, // protected_instructions OwnedVector<ProtectedInstructionData>{}, // protected_instructions
{}, // reloc_info OwnedVector<const uint8_t>{}, // reloc_info
{}, // source_pos OwnedVector<const uint8_t>{}, // source_pos
WasmCode::kJumpTable, // kind WasmCode::kJumpTable, // kind
ExecutionTier::kNone}}; // tier ExecutionTier::kNone}}; // tier
return PublishCode(std::move(code)); return PublishCode(std::move(code));
} }
...@@ -1789,9 +1782,8 @@ std::vector<WasmCode*> NativeModule::AddCompiledCode( ...@@ -1789,9 +1782,8 @@ std::vector<WasmCode*> NativeModule::AddCompiledCode(
code_space += code_size; code_space += code_size;
generated_code.emplace_back(AddCodeWithCodeSpace( generated_code.emplace_back(AddCodeWithCodeSpace(
result.func_index, result.code_desc, result.frame_slot_count, result.func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), GetCodeKind(result),
result.source_positions.as_vector(), GetCodeKind(result),
result.result_tier, this_code_space, jump_tables)); result.result_tier, this_code_space, jump_tables));
} }
DCHECK_EQ(0, code_space.size()); DCHECK_EQ(0, code_space.size());
......
...@@ -127,12 +127,9 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -127,12 +127,9 @@ class V8_EXPORT_PRIVATE WasmCode final {
Address instruction_start() const { Address instruction_start() const {
return reinterpret_cast<Address>(instructions_.begin()); return reinterpret_cast<Address>(instructions_.begin());
} }
Vector<const byte> reloc_info() const { Vector<const byte> reloc_info() const { return reloc_info_.as_vector(); }
return {protected_instructions_data().end(),
static_cast<size_t>(reloc_info_size_)};
}
Vector<const byte> source_positions() const { Vector<const byte> source_positions() const {
return {reloc_info().end(), static_cast<size_t>(source_positions_size_)}; return source_position_table_.as_vector();
} }
// TODO(clemensb): Make this return int. // TODO(clemensb): Make this return int.
...@@ -163,15 +160,9 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -163,15 +160,9 @@ class V8_EXPORT_PRIVATE WasmCode final {
pc < reinterpret_cast<Address>(instructions_.end()); pc < reinterpret_cast<Address>(instructions_.end());
} }
Vector<const uint8_t> protected_instructions_data() const { Vector<trap_handler::ProtectedInstructionData> protected_instructions()
return {meta_data_.get(),
static_cast<size_t>(protected_instructions_size_)};
}
Vector<const trap_handler::ProtectedInstructionData> protected_instructions()
const { const {
return Vector<const trap_handler::ProtectedInstructionData>::cast( return protected_instructions_.as_vector();
protected_instructions_data());
} }
void Validate() const; void Validate() const;
...@@ -227,17 +218,15 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -227,17 +218,15 @@ class V8_EXPORT_PRIVATE WasmCode final {
int safepoint_table_offset, int handler_table_offset, int safepoint_table_offset, int handler_table_offset,
int constant_pool_offset, int code_comments_offset, int constant_pool_offset, int code_comments_offset,
int unpadded_binary_size, int unpadded_binary_size,
Vector<const byte> protected_instructions_data, OwnedVector<trap_handler::ProtectedInstructionData>
Vector<const byte> reloc_info, protected_instructions,
Vector<const byte> source_position_table, Kind kind, OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, Kind kind,
ExecutionTier tier) ExecutionTier tier)
: instructions_(instructions), : instructions_(instructions),
reloc_info_(std::move(reloc_info)),
source_position_table_(std::move(source_position_table)),
native_module_(native_module), native_module_(native_module),
meta_data_(ConcatenateBytes(
{protected_instructions_data, reloc_info, source_position_table})),
reloc_info_size_(reloc_info.length()),
source_positions_size_(source_position_table.length()),
protected_instructions_size_(protected_instructions_data.length()),
index_(index), index_(index),
kind_(kind), kind_(kind),
constant_pool_offset_(constant_pool_offset), constant_pool_offset_(constant_pool_offset),
...@@ -247,6 +236,7 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -247,6 +236,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
handler_table_offset_(handler_table_offset), handler_table_offset_(handler_table_offset),
code_comments_offset_(code_comments_offset), code_comments_offset_(code_comments_offset),
unpadded_binary_size_(unpadded_binary_size), unpadded_binary_size_(unpadded_binary_size),
protected_instructions_(std::move(protected_instructions)),
tier_(tier) { tier_(tier) {
DCHECK_LE(safepoint_table_offset, unpadded_binary_size); DCHECK_LE(safepoint_table_offset, unpadded_binary_size);
DCHECK_LE(handler_table_offset, unpadded_binary_size); DCHECK_LE(handler_table_offset, unpadded_binary_size);
...@@ -254,9 +244,6 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -254,9 +244,6 @@ class V8_EXPORT_PRIVATE WasmCode final {
DCHECK_LE(constant_pool_offset, unpadded_binary_size); DCHECK_LE(constant_pool_offset, unpadded_binary_size);
} }
std::unique_ptr<const byte[]> ConcatenateBytes(
std::initializer_list<Vector<const byte>>);
// Code objects that have been registered with the global trap handler within // Code objects that have been registered with the global trap handler within
// this process, will have a {trap_handler_index} associated with them. // this process, will have a {trap_handler_index} associated with them.
int trap_handler_index() const { int trap_handler_index() const {
...@@ -278,16 +265,9 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -278,16 +265,9 @@ class V8_EXPORT_PRIVATE WasmCode final {
V8_NOINLINE bool DecRefOnPotentiallyDeadCode(); V8_NOINLINE bool DecRefOnPotentiallyDeadCode();
Vector<byte> instructions_; Vector<byte> instructions_;
OwnedVector<const byte> reloc_info_;
OwnedVector<const byte> source_position_table_;
NativeModule* native_module_ = nullptr; NativeModule* native_module_ = nullptr;
// {meta_data_} contains several byte vectors concatenated into one:
// - protected instructions data of size {protected_instructions_size_}
// - relocation info of size {reloc_info_size_}
// - source positions of size {source_positions_size_}
// Note that the protected instructions come first to ensure alignment.
std::unique_ptr<const byte[]> meta_data_;
const int reloc_info_size_;
const int source_positions_size_;
const int protected_instructions_size_;
int index_; int index_;
Kind kind_; Kind kind_;
int constant_pool_offset_ = 0; int constant_pool_offset_ = 0;
...@@ -302,6 +282,7 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -302,6 +282,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
int code_comments_offset_ = 0; int code_comments_offset_ = 0;
int unpadded_binary_size_ = 0; int unpadded_binary_size_ = 0;
int trap_handler_index_ = -1; int trap_handler_index_ = -1;
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions_;
ExecutionTier tier_; ExecutionTier tier_;
// WasmCode is ref counted. Counters are held by: // WasmCode is ref counted. Counters are held by:
...@@ -323,7 +304,7 @@ class V8_EXPORT_PRIVATE WasmCode final { ...@@ -323,7 +304,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
// often for rather small functions. // often for rather small functions.
// Increase the limit if needed, but first check if the size increase is // Increase the limit if needed, but first check if the size increase is
// justified. // justified.
STATIC_ASSERT(sizeof(WasmCode) <= 96); STATIC_ASSERT(sizeof(WasmCode) <= 120);
WasmCode::Kind GetCodeKind(const WasmCompilationResult& result); WasmCode::Kind GetCodeKind(const WasmCompilationResult& result);
...@@ -430,11 +411,13 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -430,11 +411,13 @@ class V8_EXPORT_PRIVATE NativeModule final {
// {AddCode} is thread safe w.r.t. other calls to {AddCode} or methods adding // {AddCode} is thread safe w.r.t. other calls to {AddCode} or methods adding
// code below, i.e. it can be called concurrently from background threads. // code below, i.e. it can be called concurrently from background threads.
// The returned code still needs to be published via {PublishCode}. // The returned code still needs to be published via {PublishCode}.
std::unique_ptr<WasmCode> AddCode(int index, const CodeDesc& desc, std::unique_ptr<WasmCode> AddCode(
int stack_slots, int tagged_parameter_slots, int index, const CodeDesc& desc, int stack_slots,
Vector<const byte> protected_instructions, int tagged_parameter_slots,
Vector<const byte> source_position_table, OwnedVector<trap_handler::ProtectedInstructionData>
WasmCode::Kind kind, ExecutionTier tier); protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier);
// {PublishCode} makes the code available to the system by entering it into // {PublishCode} makes the code available to the system by entering it into
// the code table and patching the jump table. It returns a raw pointer to the // the code table and patching the jump table. It returns a raw pointer to the
...@@ -448,9 +431,11 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -448,9 +431,11 @@ class V8_EXPORT_PRIVATE NativeModule final {
int tagged_parameter_slots, int safepoint_table_offset, int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset, int handler_table_offset, int constant_pool_offset,
int code_comments_offset, int unpadded_binary_size, int code_comments_offset, int unpadded_binary_size,
Vector<const byte> protected_instructions_data, OwnedVector<trap_handler::ProtectedInstructionData>
Vector<const byte> reloc_info, Vector<const byte> source_position_table, protected_instructions,
WasmCode::Kind kind, ExecutionTier tier); OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier);
// Adds anonymous code for testing purposes. // Adds anonymous code for testing purposes.
WasmCode* AddCodeForTesting(Handle<Code> code); WasmCode* AddCodeForTesting(Handle<Code> code);
...@@ -616,8 +601,9 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -616,8 +601,9 @@ class V8_EXPORT_PRIVATE NativeModule final {
std::unique_ptr<WasmCode> AddCodeWithCodeSpace( std::unique_ptr<WasmCode> AddCodeWithCodeSpace(
int index, const CodeDesc& desc, int stack_slots, int index, const CodeDesc& desc, int stack_slots,
int tagged_parameter_slots, int tagged_parameter_slots,
Vector<const byte> protected_instructions_data, OwnedVector<trap_handler::ProtectedInstructionData>
Vector<const byte> source_position_table, WasmCode::Kind kind, protected_instructions,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
ExecutionTier tier, Vector<uint8_t> code_space, ExecutionTier tier, Vector<uint8_t> code_space,
const JumpTablesRef& jump_tables_ref); const JumpTablesRef& jump_tables_ref);
......
...@@ -900,9 +900,8 @@ void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info, ...@@ -900,9 +900,8 @@ void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info,
module->functions[func_index].sig); module->functions[func_index].sig);
std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode( std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
func_index, result.code_desc, result.frame_slot_count, func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), wasm::WasmCode::kInterpreterEntry,
result.source_positions.as_vector(), wasm::WasmCode::kInterpreterEntry,
wasm::ExecutionTier::kInterpreter); wasm::ExecutionTier::kInterpreter);
native_module->PublishCode(std::move(wasm_code)); native_module->PublishCode(std::move(wasm_code));
DCHECK(native_module->IsRedirectedToInterpreter(func_index)); DCHECK(native_module->IsRedirectedToInterpreter(func_index));
......
...@@ -1460,9 +1460,8 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable( ...@@ -1460,9 +1460,8 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
isolate->wasm_engine(), &env, kind, sig, false); isolate->wasm_engine(), &env, kind, sig, false);
std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode( std::unique_ptr<wasm::WasmCode> wasm_code = native_module->AddCode(
result.func_index, result.code_desc, result.frame_slot_count, result.func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), GetCodeKind(result),
result.source_positions.as_vector(), GetCodeKind(result),
wasm::ExecutionTier::kNone); wasm::ExecutionTier::kNone);
wasm::WasmCode* published_code = wasm::WasmCode* published_code =
native_module->PublishCode(std::move(wasm_code)); native_module->PublishCode(std::move(wasm_code));
......
...@@ -99,17 +99,16 @@ class Reader { ...@@ -99,17 +99,16 @@ class Reader {
return value; return value;
} }
template <typename T> void ReadVector(Vector<byte> v) {
Vector<const T> ReadVector(size_t size) { if (v.size() > 0) {
DCHECK_GE(current_size(), size); DCHECK_GE(current_size(), v.size());
Vector<const byte> bytes{pos_, size * sizeof(T)}; memcpy(v.begin(), current_location(), v.size());
pos_ += size * sizeof(T); pos_ += v.size();
}
if (FLAG_trace_wasm_serialization) { if (FLAG_trace_wasm_serialization) {
StdoutStream{} << "read vector of " << size << " elements of size " StdoutStream{} << "read vector of " << v.size() << " elements"
<< sizeof(T) << " (total size " << size * sizeof(T) << ")"
<< std::endl; << std::endl;
} }
return Vector<const T>::cast(bytes);
} }
void Skip(size_t size) { pos_ += size; } void Skip(size_t size) { pos_ += size; }
...@@ -305,7 +304,8 @@ size_t NativeModuleSerializer::MeasureCode(const WasmCode* code) const { ...@@ -305,7 +304,8 @@ size_t NativeModuleSerializer::MeasureCode(const WasmCode* code) const {
code->kind() == WasmCode::kInterpreterEntry); code->kind() == WasmCode::kInterpreterEntry);
return kCodeHeaderSize + code->instructions().size() + return kCodeHeaderSize + code->instructions().size() +
code->reloc_info().size() + code->source_positions().size() + code->reloc_info().size() + code->source_positions().size() +
code->protected_instructions_data().size(); code->protected_instructions().size() *
sizeof(trap_handler::ProtectedInstructionData);
} }
size_t NativeModuleSerializer::Measure() const { size_t NativeModuleSerializer::Measure() const {
...@@ -343,7 +343,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) { ...@@ -343,7 +343,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
writer->Write(code->instructions().length()); writer->Write(code->instructions().length());
writer->Write(code->reloc_info().length()); writer->Write(code->reloc_info().length());
writer->Write(code->source_positions().length()); writer->Write(code->source_positions().length());
writer->Write(code->protected_instructions_data().length()); writer->Write(code->protected_instructions().length());
writer->Write(code->kind()); writer->Write(code->kind());
writer->Write(code->tier()); writer->Write(code->tier());
...@@ -355,7 +355,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) { ...@@ -355,7 +355,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
// Write the reloc info, source positions, and protected code. // Write the reloc info, source positions, and protected code.
writer->WriteVector(code->reloc_info()); writer->WriteVector(code->reloc_info());
writer->WriteVector(code->source_positions()); writer->WriteVector(code->source_positions());
writer->WriteVector(code->protected_instructions_data()); writer->WriteVector(Vector<byte>::cast(code->protected_instructions()));
#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM || \ #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM || \
V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_S390X V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_S390X
// On platforms that don't support misaligned word stores, copy to an aligned // On platforms that don't support misaligned word stores, copy to an aligned
...@@ -516,17 +516,25 @@ bool NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) { ...@@ -516,17 +516,25 @@ bool NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
WasmCode::Kind kind = reader->Read<WasmCode::Kind>(); WasmCode::Kind kind = reader->Read<WasmCode::Kind>();
ExecutionTier tier = reader->Read<ExecutionTier>(); ExecutionTier tier = reader->Read<ExecutionTier>();
auto code_buffer = reader->ReadVector<byte>(code_size); Vector<const byte> code_buffer{reader->current_location(),
auto reloc_info = reader->ReadVector<byte>(reloc_size); static_cast<size_t>(code_size)};
auto source_pos = reader->ReadVector<byte>(source_position_size); reader->Skip(code_size);
OwnedVector<byte> reloc_info = OwnedVector<byte>::New(reloc_size);
reader->ReadVector(reloc_info.as_vector());
OwnedVector<byte> source_pos = OwnedVector<byte>::New(source_position_size);
reader->ReadVector(source_pos.as_vector());
auto protected_instructions = auto protected_instructions =
reader->ReadVector<byte>(protected_instructions_size); OwnedVector<trap_handler::ProtectedInstructionData>::New(
protected_instructions_size);
reader->ReadVector(Vector<byte>::cast(protected_instructions.as_vector()));
WasmCode* code = native_module_->AddDeserializedCode( WasmCode* code = native_module_->AddDeserializedCode(
fn_index, code_buffer, stack_slot_count, tagged_parameter_slots, fn_index, code_buffer, stack_slot_count, tagged_parameter_slots,
safepoint_table_offset, handler_table_offset, constant_pool_offset, safepoint_table_offset, handler_table_offset, constant_pool_offset,
code_comment_offset, unpadded_binary_size, protected_instructions, code_comment_offset, unpadded_binary_size,
std::move(reloc_info), std::move(source_pos), kind, tier); std::move(protected_instructions), std::move(reloc_info),
std::move(source_pos), kind, tier);
// Relocate the code. // Relocate the code.
int mask = RelocInfo::ModeMask(RelocInfo::WASM_CALL) | int mask = RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
......
...@@ -3753,9 +3753,9 @@ TEST(Liftoff_tier_up) { ...@@ -3753,9 +3753,9 @@ TEST(Liftoff_tier_up) {
memcpy(buffer.get(), sub_code->instructions().begin(), sub_size); memcpy(buffer.get(), sub_code->instructions().begin(), sub_size);
desc.buffer = buffer.get(); desc.buffer = buffer.get();
desc.instr_size = static_cast<int>(sub_size); desc.instr_size = static_cast<int>(sub_size);
std::unique_ptr<WasmCode> new_code = std::unique_ptr<WasmCode> new_code = native_module->AddCode(
native_module->AddCode(add.function_index(), desc, 0, 0, {}, {}, add.function_index(), desc, 0, 0, {}, OwnedVector<byte>(),
WasmCode::kFunction, ExecutionTier::kTurbofan); WasmCode::kFunction, ExecutionTier::kTurbofan);
native_module->PublishCode(std::move(new_code)); native_module->PublishCode(std::move(new_code));
// Second run should now execute {sub}. // Second run should now execute {sub}.
......
...@@ -144,9 +144,8 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig, ...@@ -144,9 +144,8 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
sig); sig);
std::unique_ptr<wasm::WasmCode> code = native_module_->AddCode( std::unique_ptr<wasm::WasmCode> code = native_module_->AddCode(
index, result.code_desc, result.frame_slot_count, index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, result.tagged_parameter_slots, std::move(result.protected_instructions),
result.protected_instructions_data.as_vector(), std::move(result.source_positions), wasm::WasmCode::kInterpreterEntry,
result.source_positions.as_vector(), wasm::WasmCode::kInterpreterEntry,
wasm::ExecutionTier::kInterpreter); wasm::ExecutionTier::kInterpreter);
native_module_->PublishCode(std::move(code)); native_module_->PublishCode(std::move(code));
} }
......
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