Commit 79398ab0 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

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