mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 13:45:27 +00:00
Bug 1291476 - Baldr: add Instance-to-WasmInstanceObject edge (r=terrence)
MozReview-Commit-ID: EgX6342KaHJ
This commit is contained in:
parent
b081892756
commit
043c7d716a
@ -29,7 +29,6 @@ using namespace wasm;
|
||||
|
||||
Compartment::Compartment(Zone* zone)
|
||||
: mutatingInstances_(false),
|
||||
instanceObjects_(zone, InstanceObjectSet()),
|
||||
activationCount_(0),
|
||||
profilingEnabled_(false)
|
||||
{}
|
||||
@ -37,7 +36,6 @@ Compartment::Compartment(Zone* zone)
|
||||
Compartment::~Compartment()
|
||||
{
|
||||
MOZ_ASSERT(activationCount_ == 0);
|
||||
MOZ_ASSERT(!instanceObjects_.initialized() || instanceObjects_.empty());
|
||||
MOZ_ASSERT(instances_.empty());
|
||||
MOZ_ASSERT(!mutatingInstances_);
|
||||
}
|
||||
@ -63,8 +61,10 @@ Compartment::trace(JSTracer* trc)
|
||||
// unreachable while executing on the stack. Since wasm does not otherwise
|
||||
// scan the stack during GC to identify live instances, we mark all instance
|
||||
// objects live if there is any running wasm in the compartment.
|
||||
if (activationCount_)
|
||||
instanceObjects_.get().trace(trc);
|
||||
if (activationCount_) {
|
||||
for (Instance* i : instances_)
|
||||
i->trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -76,16 +76,6 @@ Compartment::registerInstance(JSContext* cx, HandleWasmInstanceObject instanceOb
|
||||
if (!instance.ensureProfilingState(cx, profilingEnabled_))
|
||||
return false;
|
||||
|
||||
if (!instanceObjects_.initialized() && !instanceObjects_.init()) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!instanceObjects_.putNew(instanceObj)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t index;
|
||||
if (BinarySearchIf(instances_, 0, instances_.length(), InstanceComparator(instance), &index))
|
||||
MOZ_CRASH("duplicate registration");
|
||||
@ -182,5 +172,5 @@ Compartment::profilingEnabled() const
|
||||
void
|
||||
Compartment::addSizeOfExcludingThis(MallocSizeOf mallocSizeOf, size_t* compartmentTables)
|
||||
{
|
||||
*compartmentTables += instanceObjects_.sizeOfExcludingThis(mallocSizeOf);
|
||||
*compartmentTables += instances_.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class WasmActivation;
|
||||
namespace wasm {
|
||||
|
||||
class Code;
|
||||
typedef Vector<Instance*, 0, SystemAllocPolicy> InstanceVector;
|
||||
|
||||
// wasm::Compartment lives in JSCompartment and contains the wasm-related
|
||||
// per-compartment state. wasm::Compartment tracks every live instance in the
|
||||
@ -36,17 +37,10 @@ class Code;
|
||||
|
||||
class Compartment
|
||||
{
|
||||
using InstanceObjectSet = GCHashSet<ReadBarriered<WasmInstanceObject*>,
|
||||
MovableCellHasher<ReadBarriered<WasmInstanceObject*>>,
|
||||
SystemAllocPolicy>;
|
||||
using WeakInstanceObjectSet = JS::WeakCache<InstanceObjectSet>;
|
||||
using InstanceVector = Vector<Instance*, 0, SystemAllocPolicy>;
|
||||
|
||||
InstanceVector instances_;
|
||||
volatile bool mutatingInstances_;
|
||||
WeakInstanceObjectSet instanceObjects_;
|
||||
size_t activationCount_;
|
||||
bool profilingEnabled_;
|
||||
InstanceVector instances_;
|
||||
volatile bool mutatingInstances_;
|
||||
size_t activationCount_;
|
||||
bool profilingEnabled_;
|
||||
|
||||
friend class js::WasmActivation;
|
||||
|
||||
@ -76,11 +70,12 @@ class Compartment
|
||||
bool registerInstance(JSContext* cx, HandleWasmInstanceObject instanceObj);
|
||||
void unregisterInstance(Instance& instance);
|
||||
|
||||
// Return a weak set of all live instances in the compartment. Accessing
|
||||
// objects of the set will trigger a read-barrier which will mark the
|
||||
// object.
|
||||
// Return a vector of all live instances in the compartment. The lifetime of
|
||||
// these Instances is determined by their owning WasmInstanceObject.
|
||||
// Note that accessing instances()[i]->object() triggers a read barrier
|
||||
// since instances() is effectively a weak list.
|
||||
|
||||
const WeakInstanceObjectSet& instanceObjects() const { return instanceObjects_; }
|
||||
const InstanceVector& instances() const { return instances_; }
|
||||
|
||||
// This methods returns the wasm::Code containing the given pc, if any
|
||||
// exists in the compartment.
|
||||
|
@ -271,12 +271,14 @@ Instance::callImport_f64(Instance* instance, int32_t funcImportIndex, int32_t ar
|
||||
}
|
||||
|
||||
Instance::Instance(JSContext* cx,
|
||||
Handle<WasmInstanceObject*> object,
|
||||
UniqueCode code,
|
||||
HandleWasmMemoryObject memory,
|
||||
SharedTableVector&& tables,
|
||||
Handle<FunctionVector> funcImports,
|
||||
const ValVector& globalImports)
|
||||
: compartment_(cx->compartment()),
|
||||
object_(object),
|
||||
code_(Move(code)),
|
||||
memory_(memory),
|
||||
tables_(Move(tables))
|
||||
@ -380,8 +382,16 @@ Instance::~Instance()
|
||||
void
|
||||
Instance::trace(JSTracer* trc)
|
||||
{
|
||||
// Ordinarily, an Instance is only marked via WasmInstanceObject's trace
|
||||
// hook and so this TraceEdge() call is only useful to update the pointer on
|
||||
// moving GC. However, if wasm is active in a wasm::Compartment during GC,
|
||||
// all Instances are marked directly via Instance::trace() making this a
|
||||
// necessary strong edge.
|
||||
TraceEdge(trc, &object_, "wasm object");
|
||||
|
||||
for (const FuncImport& fi : metadata().funcImports)
|
||||
TraceNullableEdge(trc, &funcImportToExit(fi).fun, "wasm function import");
|
||||
|
||||
TraceNullableEdge(trc, &memory_, "wasm buffer");
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
namespace js {
|
||||
|
||||
class WasmActivation;
|
||||
class WasmInstanceObject;
|
||||
|
||||
namespace wasm {
|
||||
|
||||
@ -40,6 +39,7 @@ namespace wasm {
|
||||
class Instance
|
||||
{
|
||||
JSCompartment* const compartment_;
|
||||
ReadBarrieredWasmInstanceObject object_;
|
||||
const UniqueCode code_;
|
||||
GCPtrWasmMemoryObject memory_;
|
||||
SharedTableVector tables_;
|
||||
@ -66,6 +66,7 @@ class Instance
|
||||
|
||||
public:
|
||||
Instance(JSContext* cx,
|
||||
Handle<WasmInstanceObject*> object,
|
||||
UniqueCode code,
|
||||
HandleWasmMemoryObject memory,
|
||||
SharedTableVector&& tables,
|
||||
@ -86,6 +87,12 @@ class Instance
|
||||
SharedMem<uint8_t*> memoryBase() const;
|
||||
size_t memoryLength() const;
|
||||
|
||||
// This method returns a pointer to the GC object that owns this Instance.
|
||||
// Instances may be reached via weak edges (e.g., Compartment::instances_)
|
||||
// so this perform a read-barrier on the returned object.
|
||||
|
||||
WasmInstanceObject* object() const { return object_; }
|
||||
|
||||
// Execute the given export given the JS call arguments, storing the return
|
||||
// value in args.rval.
|
||||
|
||||
|
@ -729,6 +729,7 @@ Module::instantiate(JSContext* cx,
|
||||
return false;
|
||||
|
||||
auto instance = cx->make_unique<Instance>(cx,
|
||||
instanceObj,
|
||||
Move(code),
|
||||
memory,
|
||||
Move(tables),
|
||||
|
@ -907,6 +907,7 @@ class ScriptSourceObject;
|
||||
class Shape;
|
||||
class BaseShape;
|
||||
class UnownedBaseShape;
|
||||
class WasmInstanceObject;
|
||||
namespace jit {
|
||||
class JitCode;
|
||||
} // namespace jit
|
||||
@ -958,6 +959,7 @@ typedef ReadBarriered<Shape*> ReadBarrieredShape;
|
||||
typedef ReadBarriered<jit::JitCode*> ReadBarrieredJitCode;
|
||||
typedef ReadBarriered<ObjectGroup*> ReadBarrieredObjectGroup;
|
||||
typedef ReadBarriered<JS::Symbol*> ReadBarrieredSymbol;
|
||||
typedef ReadBarriered<WasmInstanceObject*> ReadBarrieredWasmInstanceObject;
|
||||
|
||||
typedef ReadBarriered<Value> ReadBarrieredValue;
|
||||
|
||||
|
@ -50,7 +50,6 @@ class Shape;
|
||||
class SharedArrayBufferObject;
|
||||
class StructTypeDescr;
|
||||
class UnownedBaseShape;
|
||||
class WasmInstanceObject;
|
||||
class WasmMemoryObject;
|
||||
namespace jit {
|
||||
class JitCode;
|
||||
|
@ -927,7 +927,6 @@ JSCompartment::clearTables()
|
||||
MOZ_ASSERT(!debugScopes);
|
||||
MOZ_ASSERT(enumerators->next() == enumerators);
|
||||
MOZ_ASSERT(regExps.empty());
|
||||
MOZ_ASSERT(!wasm.instanceObjects().initialized() || wasm.instanceObjects().empty());
|
||||
|
||||
objectGroups.clearTables();
|
||||
if (baseShapes.initialized())
|
||||
|
@ -4167,11 +4167,8 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
|
||||
// TODOshu: Until such time that wasm modules are real ES6 modules,
|
||||
// unconditionally consider all wasm toplevel instance scripts.
|
||||
for (WeakGlobalObjectSet::Range r = debugger->allDebuggees(); !r.empty(); r.popFront()) {
|
||||
auto& instanceObjects = r.front()->compartment()->wasm.instanceObjects();
|
||||
if (!instanceObjects.initialized())
|
||||
continue;
|
||||
for (auto i = instanceObjects.all(); !i.empty(); i.popFront())
|
||||
consider(i.front());
|
||||
for (wasm::Instance* instance : r.front()->compartment()->wasm.instances())
|
||||
consider(instance->object());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user