Commit 502fc406 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Avoid embedding {undefined} into {WasmCode}.

This removes the last embedded objects from {WasmCode} objects. We still
embedded the {undefined} value into Wasm-to-JS wrappers, those are now
loaded from the instance object similar to {null} values. The relocation
information for {WasmCode} now no longer contains {EMBEDDED_OBJECT} as
entries anywhere. Another step towards making code Isolate independent.

R=titzer@chromium.org
BUG=v8:7424

Change-Id: I720cd0230948f2063770595ceded373d9bb1e87d
Reviewed-on: https://chromium-review.googlesource.com/1075268
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53408}
parent e966dcd4
...@@ -4178,8 +4178,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4178,8 +4178,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* if_not_smi = graph()->NewNode(common->IfTrue(), branch); Node* if_not_smi = graph()->NewNode(common->IfTrue(), branch);
Node* vnot_smi; Node* vnot_smi;
Node* check_undefined = graph()->NewNode(machine->WordEqual(), value, Node* undefined_node =
jsgraph()->UndefinedConstant()); LOAD_INSTANCE_FIELD(UndefinedValue, MachineType::TaggedPointer());
Node* check_undefined =
graph()->NewNode(machine->WordEqual(), value, undefined_node);
Node* branch_undefined = graph()->NewNode( Node* branch_undefined = graph()->NewNode(
common->Branch(BranchHint::kFalse), check_undefined, if_not_smi); common->Branch(BranchHint::kFalse), check_undefined, if_not_smi);
...@@ -4222,8 +4224,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4222,8 +4224,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
return BuildChangeFloat64ToTagged(node); return BuildChangeFloat64ToTagged(node);
case wasm::kWasmAnyRef: case wasm::kWasmAnyRef:
return node; return node;
case wasm::kWasmStmt:
return jsgraph()->UndefinedConstant();
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -4333,7 +4333,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4333,7 +4333,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// js_context independent. // js_context independent.
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, js_context, BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, js_context,
nullptr, 0); nullptr, 0);
Return(jsgraph()->UndefinedConstant()); Return(jsgraph()->SmiConstant(0));
return; return;
} }
...@@ -4389,7 +4389,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4389,7 +4389,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* callables_node = LOAD_INSTANCE_FIELD(ImportedFunctionCallables, Node* callables_node = LOAD_INSTANCE_FIELD(ImportedFunctionCallables,
MachineType::TaggedPointer()); MachineType::TaggedPointer());
Node* callable_node = LOAD_FIXED_ARRAY_SLOT(callables_node, index); Node* callable_node = LOAD_FIXED_ARRAY_SLOT(callables_node, index);
Node* undefined_node = jsgraph()->UndefinedConstant(); Node* undefined_node =
LOAD_INSTANCE_FIELD(UndefinedValue, MachineType::TaggedPointer());
Node* native_context = Node* native_context =
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()); LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer());
...@@ -4759,9 +4760,6 @@ void ValidateImportWrapperReferencesImmovables(Handle<Code> wrapper) { ...@@ -4759,9 +4760,6 @@ void ValidateImportWrapperReferencesImmovables(Handle<Code> wrapper) {
// we didn't link yet. // we didn't link yet.
target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
break; break;
case RelocInfo::EMBEDDED_OBJECT:
target = it.rinfo()->target_object();
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -277,11 +277,6 @@ void WasmCode::Validate() const { ...@@ -277,11 +277,6 @@ void WasmCode::Validate() const {
case RelocInfo::VENEER_POOL: case RelocInfo::VENEER_POOL:
// These are OK to appear. // These are OK to appear.
break; break;
case RelocInfo::EMBEDDED_OBJECT: {
HeapObject* o = it.rinfo()->target_object();
DCHECK(o->IsUndefined(o->GetIsolate()));
break;
}
default: default:
FATAL("Unexpected mode: %d", mode); FATAL("Unexpected mode: %d", mode);
} }
...@@ -523,10 +518,10 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code, ...@@ -523,10 +518,10 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code,
std::move(protected_instructions), // protected_instructions std::move(protected_instructions), // protected_instructions
WasmCode::kOther, // kind WasmCode::kOther, // kind
WasmCode::kNoFlushICache); // flush_icache WasmCode::kNoFlushICache); // flush_icache
intptr_t delta = ret->instruction_start() - code->InstructionStart();
int mask = RelocInfo::kApplyMask | RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
// Apply the relocation delta by iterating over the RelocInfo.
intptr_t delta = ret->instruction_start() - code->InstructionStart();
int mask = RelocInfo::kApplyMask | RelocInfo::kCodeTargetMask;
RelocIterator orig_it(*code, mask); RelocIterator orig_it(*code, mask);
for (RelocIterator it(ret->instructions(), ret->reloc_info(), for (RelocIterator it(ret->instructions(), ret->reloc_info(),
ret->constant_pool(), mask); ret->constant_pool(), mask);
...@@ -537,13 +532,10 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code, ...@@ -537,13 +532,10 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code,
it.rinfo()->set_target_address(GetLocalAddressFor(handle(call_target)), it.rinfo()->set_target_address(GetLocalAddressFor(handle(call_target)),
SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH); SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else { } else {
if (RelocInfo::IsEmbeddedObject(it.rinfo()->rmode())) { it.rinfo()->apply(delta);
DCHECK(Heap::IsImmovable(it.rinfo()->target_object()));
} else {
it.rinfo()->apply(delta);
}
} }
} }
// Flush the i-cache here instead of in AddOwnedCode, to include the changes // Flush the i-cache here instead of in AddOwnedCode, to include the changes
// made while iterating over the RelocInfo above. // made while iterating over the RelocInfo above.
Assembler::FlushICache(ret->instructions().start(), Assembler::FlushICache(ret->instructions().start(),
...@@ -582,22 +574,16 @@ WasmCode* NativeModule::AddCode( ...@@ -582,22 +574,16 @@ WasmCode* NativeModule::AddCode(
std::move(protected_instructions), tier, WasmCode::kNoFlushICache); std::move(protected_instructions), tier, WasmCode::kNoFlushICache);
code_table_[index] = ret; code_table_[index] = ret;
// TODO(mtrofin): this is a copy and paste from Code::CopyFrom.
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::kApplyMask;
// Needed to find target_object and runtime_entry on X64
// Apply the relocation delta by iterating over the RelocInfo.
AllowDeferredHandleDereference embedding_raw_address; AllowDeferredHandleDereference embedding_raw_address;
intptr_t delta = ret->instructions().start() - desc.buffer;
int mode_mask = RelocInfo::kApplyMask | RelocInfo::kCodeTargetMask;
for (RelocIterator it(ret->instructions(), ret->reloc_info(), for (RelocIterator it(ret->instructions(), ret->reloc_info(),
ret->constant_pool(), mode_mask); ret->constant_pool(), mode_mask);
!it.done(); it.next()) { !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode(); RelocInfo::Mode mode = it.rinfo()->rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) { if (RelocInfo::IsCodeTarget(mode)) {
Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
DCHECK(p->IsUndefined(p->GetIsolate()) || p->IsNull(p->GetIsolate()));
it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else if (RelocInfo::IsCodeTarget(mode)) {
// rewrite code handles to direct pointers to the first instruction in the // rewrite code handles to direct pointers to the first instruction in the
// code object // code object
Handle<Object> p = it.rinfo()->target_object_handle(origin); Handle<Object> p = it.rinfo()->target_object_handle(origin);
...@@ -605,10 +591,10 @@ WasmCode* NativeModule::AddCode( ...@@ -605,10 +591,10 @@ WasmCode* NativeModule::AddCode(
it.rinfo()->set_target_address(GetLocalAddressFor(handle(code)), it.rinfo()->set_target_address(GetLocalAddressFor(handle(code)),
SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH); SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else { } else {
intptr_t delta = ret->instructions().start() - desc.buffer;
it.rinfo()->apply(delta); it.rinfo()->apply(delta);
} }
} }
// Flush the i-cache here instead of in AddOwnedCode, to include the changes // Flush the i-cache here instead of in AddOwnedCode, to include the changes
// made while iterating over the RelocInfo above. // made while iterating over the RelocInfo above.
Assembler::FlushICache(ret->instructions().start(), Assembler::FlushICache(ret->instructions().start(),
......
...@@ -155,6 +155,7 @@ OPTIONAL_ACCESSORS(WasmInstanceObject, managed_native_allocations, Foreign, ...@@ -155,6 +155,7 @@ OPTIONAL_ACCESSORS(WasmInstanceObject, managed_native_allocations, Foreign,
kManagedNativeAllocationsOffset) kManagedNativeAllocationsOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, managed_indirect_patcher, Foreign, OPTIONAL_ACCESSORS(WasmInstanceObject, managed_indirect_patcher, Foreign,
kManagedIndirectPatcherOffset) kManagedIndirectPatcherOffset)
ACCESSORS(WasmInstanceObject, undefined_value, Oddball, kUndefinedValueOffset)
ACCESSORS(WasmInstanceObject, null_value, Oddball, kNullValueOffset) ACCESSORS(WasmInstanceObject, null_value, Oddball, kNullValueOffset)
inline bool WasmInstanceObject::has_indirect_function_table() { inline bool WasmInstanceObject::has_indirect_function_table() {
......
...@@ -805,6 +805,7 @@ Handle<WasmInstanceObject> WasmInstanceObject::New( ...@@ -805,6 +805,7 @@ Handle<WasmInstanceObject> WasmInstanceObject::New(
instance->set_compiled_module(*compiled_module); instance->set_compiled_module(*compiled_module);
instance->set_native_context(*isolate->native_context()); instance->set_native_context(*isolate->native_context());
instance->set_module_object(*module_object); instance->set_module_object(*module_object);
instance->set_undefined_value(isolate->heap()->undefined_value());
instance->set_null_value(isolate->heap()->null_value()); instance->set_null_value(isolate->heap()->null_value());
return instance; return instance;
......
...@@ -288,6 +288,7 @@ class WasmInstanceObject : public JSObject { ...@@ -288,6 +288,7 @@ class WasmInstanceObject : public JSObject {
DECL_OPTIONAL_ACCESSORS(indirect_function_table_instances, FixedArray) DECL_OPTIONAL_ACCESSORS(indirect_function_table_instances, FixedArray)
DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign) DECL_OPTIONAL_ACCESSORS(managed_native_allocations, Foreign)
DECL_OPTIONAL_ACCESSORS(managed_indirect_patcher, Foreign) DECL_OPTIONAL_ACCESSORS(managed_indirect_patcher, Foreign)
DECL_ACCESSORS(undefined_value, Oddball)
DECL_ACCESSORS(null_value, Oddball) DECL_ACCESSORS(null_value, Oddball)
DECL_PRIMITIVE_ACCESSORS(memory_start, byte*) DECL_PRIMITIVE_ACCESSORS(memory_start, byte*)
DECL_PRIMITIVE_ACCESSORS(memory_size, uint32_t) DECL_PRIMITIVE_ACCESSORS(memory_size, uint32_t)
...@@ -319,6 +320,7 @@ class WasmInstanceObject : public JSObject { ...@@ -319,6 +320,7 @@ class WasmInstanceObject : public JSObject {
V(kIndirectFunctionTableInstancesOffset, kPointerSize) \ V(kIndirectFunctionTableInstancesOffset, kPointerSize) \
V(kManagedNativeAllocationsOffset, kPointerSize) \ V(kManagedNativeAllocationsOffset, kPointerSize) \
V(kManagedIndirectPatcherOffset, kPointerSize) \ V(kManagedIndirectPatcherOffset, kPointerSize) \
V(kUndefinedValueOffset, kPointerSize) \
V(kNullValueOffset, kPointerSize) \ V(kNullValueOffset, kPointerSize) \
V(kFirstUntaggedOffset, 0) /* marker */ \ V(kFirstUntaggedOffset, 0) /* marker */ \
V(kMemoryStartOffset, kPointerSize) /* untagged */ \ V(kMemoryStartOffset, kPointerSize) /* untagged */ \
......
...@@ -480,9 +480,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) { ...@@ -480,9 +480,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
WasmCode::kNoFlushICache); WasmCode::kNoFlushICache);
native_module_->code_table_[fn_index] = ret; native_module_->code_table_[fn_index] = ret;
// now relocate the code // Relocate the code.
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::WASM_CODE_TABLE_ENTRY); RelocInfo::ModeMask(RelocInfo::WASM_CODE_TABLE_ENTRY);
for (RelocIterator iter(ret->instructions(), ret->reloc_info(), for (RelocIterator iter(ret->instructions(), ret->reloc_info(),
...@@ -490,12 +489,6 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) { ...@@ -490,12 +489,6 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
!iter.done(); iter.next()) { !iter.done(); iter.next()) {
RelocInfo::Mode mode = iter.rinfo()->rmode(); RelocInfo::Mode mode = iter.rinfo()->rmode();
switch (mode) { switch (mode) {
case RelocInfo::EMBEDDED_OBJECT: {
// We only expect {undefined}. We check for that when we add code.
iter.rinfo()->set_target_object(isolate_->heap()->undefined_value(),
SKIP_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
break;
}
case RelocInfo::CODE_TARGET: { case RelocInfo::CODE_TARGET: {
uint32_t tag = GetWasmCalleeTag(iter.rinfo()); uint32_t tag = GetWasmCalleeTag(iter.rinfo());
Address target = GetBuiltinTrampolineFromTag(tag); Address target = GetBuiltinTrampolineFromTag(tag);
......
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