Bug 1364615 - Baldr: remove bytecode from wasm::Code (r=lth)

MozReview-Commit-ID: 10FncpKzcFR
This commit is contained in:
Luke Wagner 2017-05-15 14:30:21 -05:00
parent 81dc873c58
commit cd63304f36
11 changed files with 54 additions and 65 deletions

View File

@ -572,15 +572,11 @@ Metadata::getFuncName(const Bytes* maybeBytecode, uint32_t funcIndex, UTF8Bytes*
name->append(afterFuncIndex, strlen(afterFuncIndex));
}
Code::Code(UniqueConstCodeSegment segment,
const Metadata& metadata,
const ShareableBytes* maybeBytecode)
Code::Code(UniqueConstCodeSegment segment, const Metadata& metadata)
: segment_(Move(segment)),
metadata_(&metadata),
maybeBytecode_(maybeBytecode),
profilingLabels_(mutexid::WasmCodeProfilingLabels, CacheableCharsVector())
{
MOZ_ASSERT_IF(metadata_->debugEnabled, maybeBytecode);
}
Code::Code()
@ -638,13 +634,8 @@ Code::deserialize(const uint8_t* cursor, const SharedBytes& bytecode, const Link
if (!cursor)
return nullptr;
const ShareableBytes* maybeBytecode = nullptr;
if (metadata->debugEnabled || !metadata->funcNames.empty())
maybeBytecode = bytecode.get();
segment_ = UniqueConstCodeSegment(codeSegment.release());
metadata_ = metadata;
maybeBytecode_ = maybeBytecode;
return cursor;
}
@ -695,29 +686,12 @@ Code::lookupMemoryAccess(void* pc) const
return &metadata().memoryAccesses[match];
}
bool
Code::getFuncName(uint32_t funcIndex, UTF8Bytes* name) const
{
const Bytes* maybeBytecode = maybeBytecode_ ? &maybeBytecode_.get()->bytes : nullptr;
return metadata().getFuncName(maybeBytecode, funcIndex, name);
}
JSAtom*
Code::getFuncAtom(JSContext* cx, uint32_t funcIndex) const
{
UTF8Bytes name;
if (!getFuncName(funcIndex, &name))
return nullptr;
return AtomizeUTF8Chars(cx, name.begin(), name.length());
}
// When enabled, generate profiling labels for every name in funcNames_ that is
// the name of some Function CodeRange. This involves malloc() so do it now
// since, once we start sampling, we'll be in a signal-handing context where we
// cannot malloc.
void
Code::ensureProfilingLabels(bool profilingEnabled) const
Code::ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) const
{
auto labels = profilingLabels_.lock();
@ -738,7 +712,9 @@ Code::ensureProfilingLabels(bool profilingEnabled) const
MOZ_ASSERT(bytecodeStr);
UTF8Bytes name;
if (!getFuncName(codeRange.funcIndex(), &name) || !name.append(" (", 2))
if (!metadata_->getFuncName(maybeBytecode, codeRange.funcIndex(), &name))
return;
if (!name.append(" (", 2))
return;
if (const char* filename = metadata().filename.get()) {
@ -782,7 +758,6 @@ Code::profilingLabel(uint32_t funcIndex) const
void
Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
Metadata::SeenSet* seenMetadata,
ShareableBytes::SeenSet* seenBytes,
Code::SeenSet* seenCode,
size_t* code,
size_t* data) const
@ -798,7 +773,4 @@ Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
profilingLabels_.lock()->sizeOfExcludingThis(mallocSizeOf);
segment_->addSizeOfMisc(mallocSizeOf, code, data);
if (maybeBytecode_)
*data += maybeBytecode_->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenBytes);
}

View File

@ -399,15 +399,12 @@ class Code : public ShareableBase<Code>
{
UniqueConstCodeSegment segment_;
SharedMetadata metadata_;
SharedBytes maybeBytecode_;
ExclusiveData<CacheableCharsVector> profilingLabels_;
public:
Code();
Code(UniqueConstCodeSegment segment,
const Metadata& metadata,
const ShareableBytes* maybeBytecode);
Code(UniqueConstCodeSegment segment, const Metadata& metadata);
const CodeSegment& segment() const { return *segment_; }
const Metadata& metadata() const { return *metadata_; }
@ -418,23 +415,16 @@ class Code : public ShareableBase<Code>
const CodeRange* lookupRange(void* pc) const;
const MemoryAccess* lookupMemoryAccess(void* pc) const;
// Return the name associated with a given function index, or generate one
// if none was given by the module.
bool getFuncName(uint32_t funcIndex, UTF8Bytes* name) const;
JSAtom* getFuncAtom(JSContext* cx, uint32_t funcIndex) const;
// To save memory, profilingLabels_ are generated lazily when profiling mode
// is enabled.
void ensureProfilingLabels(bool profilingEnabled) const;
void ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) const;
const char* profilingLabel(uint32_t funcIndex) const;
// about:memory reporting:
void addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
Metadata::SeenSet* seenMetadata,
ShareableBytes::SeenSet* seenBytes,
Code::SeenSet* seenCode,
size_t* code,
size_t* data) const;

View File

@ -62,7 +62,7 @@ Compartment::registerInstance(JSContext* cx, HandleWasmInstanceObject instanceOb
Instance& instance = instanceObj->instance();
MOZ_ASSERT(this == &instance.compartment()->wasm);
instance.code().ensureProfilingLabels(cx->runtime()->geckoProfiler().enabled());
instance.ensureProfilingLabels(cx->runtime()->geckoProfiler().enabled());
if (instance.debugEnabled() &&
instance.compartment()->debuggerObservesAllExecution())
@ -130,7 +130,7 @@ void
Compartment::ensureProfilingLabels(bool profilingEnabled)
{
for (Instance* instance : instances_)
instance->code().ensureProfilingLabels(profilingEnabled);
instance->ensureProfilingLabels(profilingEnabled);
}
void

View File

@ -530,7 +530,7 @@ DebugState::addSizeOfMisc(MallocSizeOf mallocSizeOf,
size_t* code,
size_t* data) const
{
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenCode, code, data);
if (maybeSourceMap_)
*data += maybeSourceMap_->sizeOfExcludingThis(mallocSizeOf);
if (maybeBytecode_)

View File

@ -97,8 +97,9 @@ class DebugState
bool ensureSourceMap(JSContext* cx);
public:
DebugState(SharedCode code,
const ShareableBytes* maybeBytecode);
DebugState(SharedCode code, const ShareableBytes* maybeBytecode);
const Bytes* maybeBytecode() const { return maybeBytecode_ ? &maybeBytecode_->bytes : nullptr; }
// If the source bytecode was saved when this Code was constructed, this
// method will render the binary as text. Otherwise, a diagnostic string

View File

@ -174,7 +174,7 @@ FrameIterator::functionDisplayAtom() const
MOZ_ASSERT(!done());
JSContext* cx = activation_->cx();
JSAtom* atom = code_->getFuncAtom(cx, codeRange_->funcIndex());
JSAtom* atom = instance()->getFuncAtom(cx, codeRange_->funcIndex());
if (!atom) {
cx->clearPendingException();
return cx->names().empty;

View File

@ -1198,11 +1198,7 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
return nullptr;
}
const ShareableBytes* maybeBytecode = nullptr;
if (metadata_->debugEnabled || !metadata_->funcNames.empty())
maybeBytecode = &bytecode;
SharedCode code = js_new<Code>(Move(codeSegment), *metadata_, maybeBytecode);
SharedCode code = js_new<Code>(Move(codeSegment), *metadata_);
if (!code)
return nullptr;

View File

@ -758,6 +758,28 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
return true;
}
bool
Instance::getFuncName(uint32_t funcIndex, UTF8Bytes* name) const
{
return metadata().getFuncName(debug_->maybeBytecode(), funcIndex, name);
}
JSAtom*
Instance::getFuncAtom(JSContext* cx, uint32_t funcIndex) const
{
UTF8Bytes name;
if (!getFuncName(funcIndex, &name))
return nullptr;
return AtomizeUTF8Chars(cx, name.begin(), name.length());
}
void
Instance::ensureProfilingLabels(bool profilingEnabled) const
{
return code_->ensureProfilingLabels(debug_->maybeBytecode(), profilingEnabled);
}
void
Instance::onMovingGrowMemory(uint8_t* prevMemoryBase)
{
@ -808,12 +830,12 @@ Instance::addSizeOfMisc(MallocSizeOf mallocSizeOf,
size_t* data) const
{
*data += mallocSizeOf(this) + globals_->sizeOfMisc(mallocSizeOf);
debug_->addSizeOfMisc(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
for (const SharedTable& table : tables_)
*data += table->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenTables);
debug_->addSizeOfMisc(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenCode, code, data);
}
/* static */ UniqueGlobalSegment

View File

@ -134,6 +134,13 @@ class Instance
MOZ_MUST_USE bool callExport(JSContext* cx, uint32_t funcIndex, CallArgs args);
// Return the name associated with a given function index, or generate one
// if none was given by the module.
bool getFuncName(uint32_t funcIndex, UTF8Bytes* name) const;
JSAtom* getFuncAtom(JSContext* cx, uint32_t funcIndex) const;
void ensureProfilingLabels(bool profilingEnabled) const;
// Initially, calls to imports in wasm code call out through the generic
// callImport method. If the imported callee gets JIT compiled and the types
// match up, callImport will patch the code to instead call through a thunk
@ -153,6 +160,7 @@ class Instance
void onMovingGrowTable();
// Debug support:
bool debugEnabled() const { return code_->metadata().debugEnabled; }
bool enterFrameTrapsEnabled() const { return enterFrameTrapsEnabled_; }
void ensureEnterFrameTrapsState(JSContext* cx, bool enabled);

View File

@ -1132,7 +1132,7 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject
// asm.js needs to act like a normal JS function which means having the name
// from the original source and being callable as a constructor.
if (instance.isAsmJS()) {
RootedAtom name(cx, instance.code().getFuncAtom(cx, funcIndex));
RootedAtom name(cx, instance.getFuncAtom(cx, funcIndex));
if (!name)
return false;

View File

@ -367,7 +367,7 @@ Module::addSizeOfMisc(MallocSizeOf mallocSizeOf,
size_t* code,
size_t* data) const
{
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenCode, code, data);
*data += mallocSizeOf(this) +
assumptions_.sizeOfExcludingThis(mallocSizeOf) +
linkData_.sizeOfExcludingThis(mallocSizeOf) +
@ -881,12 +881,12 @@ Module::instantiate(JSContext* cx,
// bytes that we keep around for debugging instead, because the debugger
// may patch the pre-linked code at any time.
if (!codeIsBusy_.compareExchange(false, true)) {
UniqueConstCodeSegment codeSegment = CodeSegment::create(*unlinkedCodeForDebugging_,
*bytecode_, linkData_,
metadata());
auto codeSegment = CodeSegment::create(*unlinkedCodeForDebugging_, *bytecode_,
linkData_, metadata());
if (!codeSegment)
return false;
code = js_new<Code>(Move(codeSegment), metadata(), bytecode_);
code = js_new<Code>(Move(codeSegment), metadata());
if (!code)
return false;
}