summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/wasm-module.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/wasm-module.cc')
-rw-r--r--deps/v8/src/wasm/wasm-module.cc143
1 files changed, 98 insertions, 45 deletions
diff --git a/deps/v8/src/wasm/wasm-module.cc b/deps/v8/src/wasm/wasm-module.cc
index 2c8266592a..bfeeb0fbff 100644
--- a/deps/v8/src/wasm/wasm-module.cc
+++ b/deps/v8/src/wasm/wasm-module.cc
@@ -8,19 +8,20 @@
#include "src/api.h"
#include "src/assembler-inl.h"
#include "src/code-stubs.h"
+#include "src/compiler/wasm-compiler.h"
#include "src/debug/interface-types.h"
#include "src/frames-inl.h"
#include "src/objects.h"
#include "src/property-descriptor.h"
#include "src/simulator.h"
#include "src/snapshot/snapshot.h"
+#include "src/trap-handler/trap-handler.h"
#include "src/v8.h"
-
-#include "src/compiler/wasm-compiler.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-code-specialization.h"
+#include "src/wasm/wasm-heap.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -54,8 +55,8 @@ constexpr const char* WasmException::kRuntimeIdStr;
// static
constexpr const char* WasmException::kRuntimeValuesStr;
-void UnpackAndRegisterProtectedInstructions(Isolate* isolate,
- Handle<FixedArray> code_table) {
+void UnpackAndRegisterProtectedInstructionsGC(Isolate* isolate,
+ Handle<FixedArray> code_table) {
DisallowHeapAllocation no_gc;
std::vector<trap_handler::ProtectedInstructionData> unpacked;
@@ -76,29 +77,69 @@ void UnpackAndRegisterProtectedInstructions(Isolate* isolate,
byte* base = code->entry();
- const int mode_mask =
- RelocInfo::ModeMask(RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING);
- for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
+ FixedArray* protected_instructions = code->protected_instructions();
+ DCHECK(protected_instructions != nullptr);
+ for (int i = 0; i < protected_instructions->length();
+ i += Code::kTrapDataSize) {
trap_handler::ProtectedInstructionData data;
- data.instr_offset = static_cast<uint32_t>(it.rinfo()->data());
- data.landing_offset = static_cast<uint32_t>(it.rinfo()->pc() - base);
- // Check that now over-/underflow happened.
- DCHECK_EQ(it.rinfo()->data(), data.instr_offset);
- DCHECK_EQ(it.rinfo()->pc() - base, data.landing_offset);
+ data.instr_offset =
+ protected_instructions
+ ->GetValueChecked<Smi>(isolate, i + Code::kTrapCodeOffset)
+ ->value();
+ data.landing_offset =
+ protected_instructions
+ ->GetValueChecked<Smi>(isolate, i + Code::kTrapLandingOffset)
+ ->value();
unpacked.emplace_back(data);
}
+
if (unpacked.empty()) continue;
- int size = code->CodeSize();
- const int index = RegisterHandlerData(reinterpret_cast<void*>(base), size,
+ const int index = RegisterHandlerData(base, code->instruction_size(),
unpacked.size(), &unpacked[0]);
+
unpacked.clear();
+
+ // TODO(6792): No longer needed once WebAssembly code is off heap.
+ CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
+
// TODO(eholk): if index is negative, fail.
DCHECK_LE(0, index);
code->set_trap_handler_index(Smi::FromInt(index));
}
}
+void UnpackAndRegisterProtectedInstructions(Isolate* isolate,
+ wasm::NativeModule* native_module) {
+ DisallowHeapAllocation no_gc;
+
+ for (uint32_t i = native_module->num_imported_functions(),
+ e = native_module->FunctionCount();
+ i < e; ++i) {
+ wasm::WasmCode* code = native_module->GetCode(i);
+
+ if (code == nullptr || code->kind() != wasm::WasmCode::Function) {
+ continue;
+ }
+
+ if (code->HasTrapHandlerIndex()) continue;
+
+ Address base = code->instructions().start();
+
+ size_t size = code->instructions().size();
+ const int index =
+ RegisterHandlerData(base, size, code->protected_instructions().size(),
+ code->protected_instructions().data());
+
+ // TODO(6792): No longer needed once WebAssembly code is off heap.
+ CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
+
+ // TODO(eholk): if index is negative, fail.
+ CHECK_LE(0, index);
+ code->set_trap_handler_index(static_cast<size_t>(index));
+ }
+}
+
std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name) {
os << "#" << name.function_->func_index;
if (name.function_->name.is_set()) {
@@ -129,50 +170,56 @@ WasmFunction* GetWasmFunctionForExport(Isolate* isolate,
return nullptr;
}
-Handle<Code> UnwrapExportWrapper(Handle<JSFunction> export_wrapper) {
- Handle<Code> export_wrapper_code = handle(export_wrapper->code());
- DCHECK_EQ(export_wrapper_code->kind(), Code::JS_TO_WASM_FUNCTION);
- int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
- for (RelocIterator it(*export_wrapper_code, mask);; it.next()) {
- DCHECK(!it.done());
- Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
- if (target->kind() != Code::WASM_FUNCTION &&
- target->kind() != Code::WASM_TO_JS_FUNCTION &&
- target->kind() != Code::WASM_INTERPRETER_ENTRY)
- continue;
-// There should only be this one call to wasm code.
-#ifdef DEBUG
- for (it.next(); !it.done(); it.next()) {
- Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
- DCHECK(code->kind() != Code::WASM_FUNCTION &&
- code->kind() != Code::WASM_TO_JS_FUNCTION &&
- code->kind() != Code::WASM_INTERPRETER_ENTRY);
+Handle<Object> GetOrCreateIndirectCallWrapper(
+ Isolate* isolate, Handle<WasmInstanceObject> owning_instance,
+ WasmCodeWrapper wasm_code, uint32_t index, FunctionSig* sig) {
+ Address new_context_address =
+ reinterpret_cast<Address>(owning_instance->wasm_context()->get());
+ if (!wasm_code.IsCodeObject()) {
+ DCHECK_NE(wasm_code.GetWasmCode()->kind(),
+ wasm::WasmCode::WasmToWasmWrapper);
+ wasm::NativeModule* native_module = wasm_code.GetWasmCode()->owner();
+ // The only reason we pass owning_instance is for the GC case. Check
+ // that the values match.
+ DCHECK_EQ(owning_instance->compiled_module()->GetNativeModule(),
+ native_module);
+ // We create the wrapper on the module exporting the function. This
+ // wrapper will only be called as indirect call.
+ wasm::WasmCode* exported_wrapper =
+ native_module->GetExportedWrapper(wasm_code.GetWasmCode()->index());
+ if (exported_wrapper == nullptr) {
+ Handle<Code> new_wrapper = compiler::CompileWasmToWasmWrapper(
+ isolate, wasm_code, sig, new_context_address);
+ exported_wrapper = native_module->AddExportedWrapper(
+ new_wrapper, wasm_code.GetWasmCode()->index());
}
-#endif
- return handle(target);
+ Address target = exported_wrapper->instructions().start();
+ return isolate->factory()->NewForeign(target, TENURED);
}
- UNREACHABLE();
+ Handle<Code> code = compiler::CompileWasmToWasmWrapper(
+ isolate, wasm_code, sig, new_context_address);
+ AttachWasmFunctionInfo(isolate, code, owning_instance,
+ static_cast<int>(index));
+ return code;
}
void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
int index, WasmFunction* function,
- Handle<Code> code) {
+ Handle<Object> code_or_foreign) {
DCHECK_EQ(0, dispatch_tables->length() % 4);
for (int i = 0; i < dispatch_tables->length(); i += 4) {
- int table_index = Smi::ToInt(dispatch_tables->get(i + 1));
Handle<FixedArray> function_table(
FixedArray::cast(dispatch_tables->get(i + 2)), isolate);
Handle<FixedArray> signature_table(
FixedArray::cast(dispatch_tables->get(i + 3)), isolate);
if (function) {
- // TODO(titzer): the signature might need to be copied to avoid
- // a dangling pointer in the signature map.
Handle<WasmInstanceObject> instance(
WasmInstanceObject::cast(dispatch_tables->get(i)), isolate);
- auto& func_table = instance->module()->function_tables[table_index];
- uint32_t sig_index = func_table.map.FindOrInsert(function->sig);
- signature_table->set(index, Smi::FromInt(static_cast<int>(sig_index)));
- function_table->set(index, *code);
+ // Note that {SignatureMap::Find} may return {-1} if the signature is
+ // not found; it will simply never match any check.
+ auto sig_index = instance->module()->signature_map.Find(function->sig);
+ signature_table->set(index, Smi::FromInt(sig_index));
+ function_table->set(index, *code_or_foreign);
} else {
signature_table->set(index, Smi::FromInt(-1));
function_table->set(index, Smi::kZero);
@@ -185,8 +232,14 @@ bool IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
// separate callback that includes information about the module about to be
// compiled. For the time being, pass an empty string as placeholder for the
// sources.
- return isolate->allow_code_gen_callback() == nullptr ||
- isolate->allow_code_gen_callback()(
+ if (auto wasm_codegen_callback = isolate->allow_wasm_code_gen_callback()) {
+ return wasm_codegen_callback(
+ v8::Utils::ToLocal(context),
+ v8::Utils::ToLocal(isolate->factory()->empty_string()));
+ }
+ auto codegen_callback = isolate->allow_code_gen_callback();
+ return codegen_callback == nullptr ||
+ codegen_callback(
v8::Utils::ToLocal(context),
v8::Utils::ToLocal(isolate->factory()->empty_string()));
}