Commit 9d6014ad authored by mtrofin's avatar mtrofin Committed by Commit bot

Revert "Revert "[wasm] Complete separation of compilation and instantiation""

This reverts commit 1eb1dfab.

The original compilation separation change avoided associating a heap
for the wasm instance if memory was not provided, nor needed. The
grow memory CL assumed the old behavior, where a memory buffer was
always present, but may have had a zero size.

The 2CLS  landed shortly after one another. We decided to treat the
grow memory as the race condition winner, so this CL here re-lands
compilation separation, plus adjusts grow memory to deal with
the undefined mem buffer.

BUG=

Review-Url: https://codereview.chromium.org/2102193003
Cr-Commit-Position: refs/heads/master@{#37352}
parent 1eb1dfab
...@@ -2955,29 +2955,31 @@ void WasmGraphBuilder::SetSourcePosition(Node* node, ...@@ -2955,29 +2955,31 @@ void WasmGraphBuilder::SetSourcePosition(Node* node,
} }
static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
CompilationInfo* info, Isolate* isolate, Handle<Code> code,
const char* message, uint32_t index, const char* message, uint32_t index,
wasm::WasmName func_name) { const wasm::WasmName& module_name,
Isolate* isolate = info->isolate(); const wasm::WasmName& func_name) {
if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) { DCHECK(isolate->logger()->is_logging_code_events() ||
isolate->is_profiling());
ScopedVector<char> buffer(128); ScopedVector<char> buffer(128);
SNPrintF(buffer, "%s#%d:%.*s", message, index, func_name.length(), SNPrintF(buffer, "%s#%d:%.*s:%.*s", message, index, module_name.length(),
func_name.start()); module_name.start(), func_name.length(), func_name.start());
Handle<String> name_str = Handle<String> name_str =
isolate->factory()->NewStringFromAsciiChecked(buffer.start()); isolate->factory()->NewStringFromAsciiChecked(buffer.start());
Handle<String> script_str = Handle<String> script_str =
isolate->factory()->NewStringFromAsciiChecked("(WASM)"); isolate->factory()->NewStringFromAsciiChecked("(WASM)");
Handle<Code> code = info->code();
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfo(name_str, code, false); isolate->factory()->NewSharedFunctionInfo(name_str, code, false);
PROFILE(isolate, CodeCreateEvent(tag, AbstractCode::cast(*code), *shared, PROFILE(isolate, CodeCreateEvent(tag, AbstractCode::cast(*code), *shared,
*script_str, 0, 0)); *script_str, 0, 0));
}
} }
Handle<JSFunction> CompileJSToWasmWrapper( Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate,
Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name, wasm::ModuleEnv* module,
Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index) { Handle<String> name,
Handle<Code> wasm_code,
uint32_t index) {
const wasm::WasmFunction* func = &module->module->functions[index]; const wasm::WasmFunction* func = &module->module->functions[index];
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -2990,7 +2992,6 @@ Handle<JSFunction> CompileJSToWasmWrapper( ...@@ -2990,7 +2992,6 @@ Handle<JSFunction> CompileJSToWasmWrapper(
shared->set_internal_formal_parameter_count(params); shared->set_internal_formal_parameter_count(params);
Handle<JSFunction> function = isolate->factory()->NewFunction( Handle<JSFunction> function = isolate->factory()->NewFunction(
isolate->wasm_function_map(), name, MaybeHandle<Code>()); isolate->wasm_function_map(), name, MaybeHandle<Code>());
function->SetInternalField(0, *module_object);
function->set_shared(*shared); function->set_shared(*shared);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -3056,9 +3057,13 @@ Handle<JSFunction> CompileJSToWasmWrapper( ...@@ -3056,9 +3057,13 @@ Handle<JSFunction> CompileJSToWasmWrapper(
buffer.Dispose(); buffer.Dispose();
} }
if (isolate->logger()->is_logging_code_events() ||
isolate->is_profiling()) {
RecordFunctionCompilation( RecordFunctionCompilation(
CodeEventListener::FUNCTION_TAG, &info, "js-to-wasm", index, CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index,
wasm::WasmName("export"),
module->module->GetName(func->name_offset, func->name_length)); module->module->GetName(func->name_offset, func->name_length));
}
// Set the JSFunction's machine code. // Set the JSFunction's machine code.
function->set_code(*code); function->set_code(*code);
} }
...@@ -3067,9 +3072,9 @@ Handle<JSFunction> CompileJSToWasmWrapper( ...@@ -3067,9 +3072,9 @@ Handle<JSFunction> CompileJSToWasmWrapper(
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<Code> CompileWasmToJSWrapper(Isolate* isolate,
Handle<JSFunction> function, Handle<JSFunction> function,
wasm::FunctionSig* sig, wasm::FunctionSig* sig, uint32_t index,
wasm::WasmName module_name, Handle<String> import_module,
wasm::WasmName function_name) { MaybeHandle<String> import_function) {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Create the Graph // Create the Graph
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -3128,10 +3133,21 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, ...@@ -3128,10 +3133,21 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate,
if (debugging) { if (debugging) {
buffer.Dispose(); buffer.Dispose();
} }
RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, &info,
"wasm-to-js", 0, module_name);
} }
if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
const char* function_name = nullptr;
int function_name_size = 0;
if (!import_function.is_null()) {
Handle<String> handle = import_function.ToHandleChecked();
function_name = handle->ToCString().get();
function_name_size = handle->length();
}
RecordFunctionCompilation(
CodeEventListener::FUNCTION_TAG, isolate, code, "wasm-to-js", index,
{import_module->ToCString().get(), import_module->length()},
{function_name, function_name_size});
}
return code; return code;
} }
...@@ -3294,11 +3310,14 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() { ...@@ -3294,11 +3310,14 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
Handle<Code> code = info_.code(); Handle<Code> code = info_.code();
DCHECK(!code.is_null()); DCHECK(!code.is_null());
if (isolate_->logger()->is_logging_code_events() ||
isolate_->is_profiling()) {
RecordFunctionCompilation( RecordFunctionCompilation(
CodeEventListener::FUNCTION_TAG, &info_, "WASM_function", CodeEventListener::FUNCTION_TAG, isolate_, code, "WASM_function",
function_->func_index, function_->func_index, wasm::WasmName("module"),
module_env_->module->GetName(function_->name_offset, module_env_->module->GetName(function_->name_offset,
function_->name_length)); function_->name_length));
}
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
double compile_ms = compile_timer.Elapsed().InMillisecondsF(); double compile_ms = compile_timer.Elapsed().InMillisecondsF();
......
...@@ -79,15 +79,17 @@ class WasmCompilationUnit final { ...@@ -79,15 +79,17 @@ class WasmCompilationUnit final {
// Wraps a JS function, producing a code object that can be called from WASM. // Wraps a JS function, producing a code object that can be called from WASM.
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<Code> CompileWasmToJSWrapper(Isolate* isolate,
Handle<JSFunction> function, Handle<JSFunction> function,
wasm::FunctionSig* sig, wasm::FunctionSig* sig, uint32_t index,
wasm::WasmName module_name, Handle<String> import_module,
wasm::WasmName function_name); MaybeHandle<String> import_function);
// Wraps a given wasm code object, producing a JSFunction that can be called // Wraps a given wasm code object, producing a JSFunction that can be called
// from JavaScript. // from JavaScript.
Handle<JSFunction> CompileJSToWasmWrapper( Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate,
Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name, wasm::ModuleEnv* module,
Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index); Handle<String> name,
Handle<Code> wasm_code,
uint32_t index);
// Abstracts details of building TurboFan graph nodes for WASM to separate // Abstracts details of building TurboFan graph nodes for WASM to separate
// the WASM decoder from the internal details of TurboFan. // the WASM decoder from the internal details of TurboFan.
......
...@@ -2306,12 +2306,24 @@ Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) { ...@@ -2306,12 +2306,24 @@ Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) {
return handle(array->get(index), isolate); return handle(array->get(index), isolate);
} }
template <class T>
MaybeHandle<T> FixedArray::GetValue(int index) const {
Object* obj = get(index);
if (obj->IsUndefined(GetIsolate())) return MaybeHandle<T>();
return Handle<T>(T::cast(obj));
}
template <class T>
Handle<T> FixedArray::GetValueChecked(int index) const {
Object* obj = get(index);
CHECK(!obj->IsUndefined(GetIsolate()));
return Handle<T>(T::cast(obj));
}
bool FixedArray::is_the_hole(int index) { bool FixedArray::is_the_hole(int index) {
return get(index) == GetHeap()->the_hole_value(); return get(index) == GetHeap()->the_hole_value();
} }
void FixedArray::set(int index, Smi* value) { void FixedArray::set(int index, Smi* value) {
DCHECK(map() != GetHeap()->fixed_cow_array_map()); DCHECK(map() != GetHeap()->fixed_cow_array_map());
DCHECK(index >= 0 && index < this->length()); DCHECK(index >= 0 && index < this->length());
...@@ -3981,6 +3993,9 @@ byte ByteArray::get(int index) { ...@@ -3981,6 +3993,9 @@ byte ByteArray::get(int index) {
return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
} }
const byte* ByteArray::data() const {
return reinterpret_cast<const byte*>(FIELD_ADDR_CONST(this, kHeaderSize));
}
void ByteArray::set(int index, byte value) { void ByteArray::set(int index, byte value) {
DCHECK(index >= 0 && index < this->length()); DCHECK(index >= 0 && index < this->length());
......
...@@ -2644,6 +2644,12 @@ class FixedArray: public FixedArrayBase { ...@@ -2644,6 +2644,12 @@ class FixedArray: public FixedArrayBase {
inline Object* get(int index) const; inline Object* get(int index) const;
static inline Handle<Object> get(FixedArray* array, int index, static inline Handle<Object> get(FixedArray* array, int index,
Isolate* isolate); Isolate* isolate);
template <class T>
MaybeHandle<T> GetValue(int index) const;
template <class T>
Handle<T> GetValueChecked(int index) const;
// Setter that uses write barrier. // Setter that uses write barrier.
inline void set(int index, Object* value); inline void set(int index, Object* value);
inline bool is_the_hole(int index); inline bool is_the_hole(int index);
...@@ -4420,6 +4426,7 @@ class ByteArray: public FixedArrayBase { ...@@ -4420,6 +4426,7 @@ class ByteArray: public FixedArrayBase {
// Setter and getter. // Setter and getter.
inline byte get(int index); inline byte get(int index);
inline void set(int index, byte value); inline void set(int index, byte value);
inline const byte* data() const;
// Copy in / copy out whole byte slices. // Copy in / copy out whole byte slices.
inline void copy_out(int index, byte* buffer, int length); inline void copy_out(int index, byte* buffer, int length);
......
...@@ -39,13 +39,11 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { ...@@ -39,13 +39,11 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
// Get mem buffer associated with module object // Get mem buffer associated with module object
Object* obj = module_object->GetInternalField(kWasmMemArrayBuffer); Object* obj = module_object->GetInternalField(kWasmMemArrayBuffer);
Handle<JSArrayBuffer> old_buffer =
Handle<JSArrayBuffer>(JSArrayBuffer::cast(obj));
if (old_buffer->byte_length()->Number() == 0) { if (obj->IsUndefined(isolate)) {
// If module object does not have linear memory associated with it, // If module object does not have linear memory associated with it,
// Allocate new array buffer of given size. // Allocate new array buffer of given size.
old_mem_start = static_cast<Address>(old_buffer->backing_store()); old_mem_start = nullptr;
old_size = 0; old_size = 0;
// TODO(gdeepti): Fix bounds check to take into account size of memtype. // TODO(gdeepti): Fix bounds check to take into account size of memtype.
new_size = delta_pages * wasm::WasmModule::kPageSize; new_size = delta_pages * wasm::WasmModule::kPageSize;
...@@ -67,8 +65,15 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { ...@@ -67,8 +65,15 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
} }
#endif #endif
} else { } else {
Handle<JSArrayBuffer> old_buffer =
Handle<JSArrayBuffer>(JSArrayBuffer::cast(obj));
old_mem_start = static_cast<Address>(old_buffer->backing_store()); old_mem_start = static_cast<Address>(old_buffer->backing_store());
old_size = old_buffer->byte_length()->Number(); old_size = old_buffer->byte_length()->Number();
// If the old memory was zero-sized, we should have been in the
// "undefined" case above.
DCHECK_NOT_NULL(old_mem_start);
DCHECK_NE(0, old_size);
new_size = old_size + delta_pages * wasm::WasmModule::kPageSize; new_size = old_size + delta_pages * wasm::WasmModule::kPageSize;
if (new_size > if (new_size >
wasm::WasmModule::kMaxMemPages * wasm::WasmModule::kPageSize) { wasm::WasmModule::kMaxMemPages * wasm::WasmModule::kPageSize) {
......
...@@ -14,7 +14,7 @@ namespace internal { ...@@ -14,7 +14,7 @@ namespace internal {
template <typename T> template <typename T>
class Signature : public ZoneObject { class Signature : public ZoneObject {
public: public:
Signature(size_t return_count, size_t parameter_count, T* reps) Signature(size_t return_count, size_t parameter_count, const T* reps)
: return_count_(return_count), : return_count_(return_count),
parameter_count_(parameter_count), parameter_count_(parameter_count),
reps_(reps) {} reps_(reps) {}
...@@ -32,6 +32,8 @@ class Signature : public ZoneObject { ...@@ -32,6 +32,8 @@ class Signature : public ZoneObject {
return reps_[index]; return reps_[index];
} }
const T* raw_data() const { return reps_; }
// For incrementally building signatures. // For incrementally building signatures.
class Builder { class Builder {
public: public:
...@@ -71,7 +73,7 @@ class Signature : public ZoneObject { ...@@ -71,7 +73,7 @@ class Signature : public ZoneObject {
protected: protected:
size_t return_count_; size_t return_count_;
size_t parameter_count_; size_t parameter_count_;
T* reps_; const T* reps_;
}; };
} // namespace internal } // namespace internal
......
...@@ -197,11 +197,16 @@ i::MaybeHandle<i::JSObject> InstantiateModuleCommon( ...@@ -197,11 +197,16 @@ i::MaybeHandle<i::JSObject> InstantiateModuleCommon(
memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj));
} }
object = result.val->Instantiate(isolate, ffi, memory); i::MaybeHandle<i::FixedArray> compiled_module =
result.val->CompileFunctions(isolate);
if (!compiled_module.is_null()) {
object = i::wasm::WasmModule::Instantiate(
isolate, compiled_module.ToHandleChecked(), ffi, memory);
if (!object.is_null()) { if (!object.is_null()) {
args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked()));
} }
} }
}
if (result.val) delete result.val; if (result.val) delete result.val;
return object; return object;
......
This diff is collapsed.
...@@ -224,10 +224,12 @@ struct WasmModule { ...@@ -224,10 +224,12 @@ struct WasmModule {
} }
// Creates a new instantiation of the module in the given isolate. // Creates a new instantiation of the module in the given isolate.
MaybeHandle<JSObject> Instantiate(Isolate* isolate, Handle<JSReceiver> ffi, static MaybeHandle<JSObject> Instantiate(Isolate* isolate,
Handle<JSArrayBuffer> memory) const; Handle<FixedArray> compiled_module,
Handle<JSReceiver> ffi,
Handle<JSArrayBuffer> memory);
Handle<FixedArray> CompileFunctions(Isolate* isolate) const; MaybeHandle<FixedArray> CompileFunctions(Isolate* isolate) const;
uint32_t FunctionTableSize() const { uint32_t FunctionTableSize() const {
if (indirect_table_size > 0) { if (indirect_table_size > 0) {
......
...@@ -186,10 +186,9 @@ class TestingModule : public ModuleEnv { ...@@ -186,10 +186,9 @@ class TestingModule : public ModuleEnv {
Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle( Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(source)))); *v8::Local<v8::Function>::Cast(CompileRun(source))));
uint32_t index = AddFunction(sig, Handle<Code>::null()); uint32_t index = AddFunction(sig, Handle<Code>::null());
WasmName module_name = ArrayVector("test"); Handle<Code> code =
WasmName function_name; CompileWasmToJSWrapper(isolate_, jsfunc, sig, index,
Handle<Code> code = CompileWasmToJSWrapper(isolate_, jsfunc, sig, Handle<String>::null(), Handle<String>::null());
module_name, function_name);
instance->function_code[index] = code; instance->function_code[index] = code;
return index; return index;
} }
...@@ -200,8 +199,10 @@ class TestingModule : public ModuleEnv { ...@@ -200,8 +199,10 @@ class TestingModule : public ModuleEnv {
Handle<JSObject> module_object = Handle<JSObject>(0, isolate_); Handle<JSObject> module_object = Handle<JSObject>(0, isolate_);
Handle<Code> code = instance->function_code[index]; Handle<Code> code = instance->function_code[index];
WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context()); WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context());
return compiler::CompileJSToWasmWrapper(isolate_, this, name, code, Handle<JSFunction> ret =
module_object, index); compiler::CompileJSToWasmWrapper(isolate_, this, name, code, index);
ret->SetInternalField(0, *module_object);
return ret;
} }
void SetFunctionCode(uint32_t index, Handle<Code> code) { void SetFunctionCode(uint32_t index, Handle<Code> 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