Skip to content

Commit

Permalink
Replace cjsModuleOffset with segmentID
Browse files Browse the repository at this point in the history
Summary:
Introduces the concept of a "segment ID" to the runtime and bytecode.

Previously, each BytecodeModule / RuntimeModule had a `cjsModuleOffset` which did double duty as (1) the offset of the first CJS module for registration in the Domain, and (2) a unique ID for each BytecodeModule / RuntimeModule for the purpose of stack traces and source maps.

Here we:

* Remove responsibility (1) because the changes to Domain in D23938175 make it unnecessary.
* Use the input segment ID (from the CommonJS metadata) as the segment ID in the corresponding BytecodeModule / RuntimeModule.
* Rename the resulting concept to `segmentID`.

Reviewed By: avp

Differential Revision: D23940758

fbshipit-source-id: 7f70179a42ca7aceb7c6a5dcfe2ad12141ddfb74
  • Loading branch information
motiz88 authored and facebook-github-bot committed Oct 8, 2020
1 parent d3c1ec3 commit c57fde2
Show file tree
Hide file tree
Showing 24 changed files with 65 additions and 73 deletions.
17 changes: 9 additions & 8 deletions include/hermes/BCGen/HBC/Bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,11 @@ class BytecodeModule {
/// Object Value Buffer table.
SerializableBufferTy objValBuffer_;

/// The ID of the first CJS module in this BytecodeModule.
/// This is the first entry in the Domain's CJS module table that will be
/// populated by the corresponding RuntimeModule.
uint32_t cjsModuleOffset_;
/// The segment ID corresponding to this BytecodeModule.
/// This uniquely identifies this BytecodeModule within a set of modules
/// which were compiled at the same time (and will correspond to a set of
/// RuntimeModules in a Domain).
uint32_t segmentID_;

/// Table which indicates where to find the different CommonJS modules.
/// Mapping from {filename ID => function index}.
Expand Down Expand Up @@ -260,7 +261,7 @@ class BytecodeModule {
std::vector<unsigned char> &&arrayBuffer,
std::vector<unsigned char> &&objKeyBuffer,
std::vector<unsigned char> &&objValBuffer,
uint32_t cjsModuleOffset,
uint32_t segmentID,
std::vector<std::pair<uint32_t, uint32_t>> &&cjsModuleTable,
std::vector<std::pair<uint32_t, uint32_t>> &&cjsModuleTableStatic,
BytecodeOptions options)
Expand All @@ -274,7 +275,7 @@ class BytecodeModule {
arrayBuffer_(std::move(arrayBuffer)),
objKeyBuffer_(std::move(objKeyBuffer)),
objValBuffer_(std::move(objValBuffer)),
cjsModuleOffset_(cjsModuleOffset),
segmentID_(segmentID),
cjsModuleTable_(std::move(cjsModuleTable)),
cjsModuleTableStatic_(std::move(cjsModuleTableStatic)),
options_(options) {
Expand Down Expand Up @@ -343,8 +344,8 @@ class BytecodeModule {
return regExpStorage_;
}

uint32_t getCJSModuleOffset() const {
return cjsModuleOffset_;
uint32_t getSegmentID() const {
return segmentID_;
}

llvh::ArrayRef<std::pair<uint32_t, uint32_t>> getCJSModuleTable() const {
Expand Down
8 changes: 4 additions & 4 deletions include/hermes/BCGen/HBC/BytecodeDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ class BCProviderBase {
llvh::ArrayRef<RegExpTableEntry> regExpTable_{};
llvh::ArrayRef<unsigned char> regExpStorage_{};

/// The ID of the first CJS module in this BytecodeModule.
uint32_t cjsModuleOffset_;
/// The segment ID corresponding to the bytecode module.
uint32_t segmentID_;

/// Table which indicates where to find the different CommonJS modules.
/// List of unsorted pairs from {filename ID => function index}.
Expand Down Expand Up @@ -187,8 +187,8 @@ class BCProviderBase {
llvh::ArrayRef<unsigned char> getRegExpStorage() const {
return regExpStorage_;
}
uint32_t getCJSModuleOffset() const {
return cjsModuleOffset_;
uint32_t getSegmentID() const {
return segmentID_;
}
llvh::ArrayRef<std::pair<uint32_t, uint32_t>> getCJSModuleTable() const {
return cjsModuleTable_;
Expand Down
8 changes: 4 additions & 4 deletions include/hermes/BCGen/HBC/BytecodeFileFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const static uint64_t DELTA_MAGIC = ~MAGIC;

// Bytecode version generated by this version of the compiler.
// Updated: Oct 5, 2020
const static uint32_t BYTECODE_VERSION = 77;
const static uint32_t BYTECODE_VERSION = 78;

/// Property cache index which indicates no caching.
static constexpr uint8_t PROPERTY_CACHING_DISABLED = 0;
Expand Down Expand Up @@ -85,7 +85,7 @@ struct BytecodeFileHeader {
uint32_t arrayBufferSize;
uint32_t objKeyBufferSize;
uint32_t objValueBufferSize;
uint32_t cjsModuleOffset; // The starting module ID in this segment.
uint32_t segmentID; // The ID of this segment.
uint32_t cjsModuleCount; // Number of modules.
uint32_t debugInfoOffset;
BytecodeOptions options;
Expand All @@ -111,7 +111,7 @@ struct BytecodeFileHeader {
uint32_t arrayBufferSize,
uint32_t objKeyBufferSize,
uint32_t objValueBufferSize,
uint32_t cjsModuleOffset,
uint32_t segmentID,
uint32_t cjsModuleCount,
uint32_t debugInfoOffset,
BytecodeOptions options)
Expand All @@ -131,7 +131,7 @@ struct BytecodeFileHeader {
arrayBufferSize(arrayBufferSize),
objKeyBufferSize(objKeyBufferSize),
objValueBufferSize(objValueBufferSize),
cjsModuleOffset(cjsModuleOffset),
segmentID(segmentID),
cjsModuleCount(cjsModuleCount),
debugInfoOffset(debugInfoOffset),
options(options) {
Expand Down
10 changes: 5 additions & 5 deletions include/hermes/BCGen/HBC/BytecodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ class BytecodeModuleGenerator {
/// This allows us to serialize the filenames as part of the debug info.
UniquingFilenameTable filenameTable_{};

/// The ID of the first CJS module in this BytecodeModule.
uint32_t cjsModuleOffset_{0};
/// The ID of this segment.
uint32_t segmentID_{0};

/// A record of all the CJS modules registered in this run of generation.
/// List of pairs: (filename ID, function index).
Expand Down Expand Up @@ -352,9 +352,9 @@ class BytecodeModuleGenerator {
/// \return the index of the string.
uint32_t addFilename(StringRef str);

/// Set the CJS module offset for this module.
void setCJSModuleOffset(uint32_t offset) {
cjsModuleOffset_ = offset;
/// Set the segment ID for this module.
void setSegmentID(uint32_t id) {
segmentID_ = id;
}

/// Adds a CJS module entry to the table.
Expand Down
2 changes: 1 addition & 1 deletion include/hermes/BCGen/HBC/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ class DebugInfo {
void populateSourceMap(
SourceMapGenerator *sourceMap,
std::vector<uint32_t> &&functionOffsets,
uint32_t cjsModuleOffset) const;
uint32_t segmentID) const;
#endif
};

Expand Down
18 changes: 9 additions & 9 deletions include/hermes/SourceMap/SourceMapGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ class SourceMapGenerator {
public:
/// Add a line \p line represented as a list of Segments to the 'mappings'
/// section.
/// \param cjsModuleOffset the offset of the module represented by the given
/// line, used as the "line" when reporting stack traces from the VM,
/// which doesn't have access to the segment IDs.
void addMappingsLine(SourceMap::SegmentList line, uint32_t cjsModuleOffset) {
if (lines_.size() <= cjsModuleOffset) {
lines_.resize(cjsModuleOffset + 1);
/// \param segmentID the ID of the segment ( = the BytecodeModule /
/// RuntimeModule), used as the "line" when reporting stack traces from the
/// VM.
void addMappingsLine(SourceMap::SegmentList line, uint32_t segmentID) {
if (lines_.size() <= segmentID) {
lines_.resize(segmentID + 1);
}
lines_[cjsModuleOffset] = std::move(line);
lines_[segmentID] = std::move(line);
}

/// \return the list of mappings lines.
Expand Down Expand Up @@ -66,7 +66,7 @@ class SourceMapGenerator {
/// SourceMapGenerator::outputAsJSON.
void addFunctionOffsets(
std::vector<uint32_t> &&functionOffsets,
uint32_t cjsModuleOffset);
uint32_t segmentID);

/// Get the source index given the filename.
uint32_t getSourceIndex(llvh::StringRef filename) const {
Expand Down Expand Up @@ -141,7 +141,7 @@ class SourceMapGenerator {
/// x_facebook_sources field in the JSON source map.
SourceMap::MetadataList sourcesMetadata_;

/// Maps cjsModuleOffset to a vector of function offsets indexed by their
/// Maps segmentID to a vector of function offsets indexed by their
/// function id.
llvh::DenseMap<uint32_t, std::vector<uint32_t>> functionOffsets_{};
};
Expand Down
2 changes: 1 addition & 1 deletion include/hermes/VM/PredefinedStrings.def
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ STR(getFunctionLocation, "getFunctionLocation")
STR(isNative, "isNative")
STR(lineNumber, "lineNumber")
STR(columnNumber, "columnNumber")
STR(cjsModuleOffset, "cjsModuleOffset")
STR(segmentID, "segmentID")
STR(virtualOffset, "virtualOffset")
STR(fileName, "fileName")

Expand Down
2 changes: 1 addition & 1 deletion lib/BCGen/HBC/Bytecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void BytecodeModule::populateSourceMap(SourceMapGenerator *sourceMap) const {
offset += func->getHeader().bytecodeSizeInBytes;
}
debugInfo_.populateSourceMap(
sourceMap, std::move(functionOffsets), cjsModuleOffset_);
sourceMap, std::move(functionOffsets), segmentID_);
}

void BytecodeModule::inlineJumpTables() {
Expand Down
2 changes: 1 addition & 1 deletion lib/BCGen/HBC/BytecodeDataProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ BCProviderFromBuffer::BCProviderFromBuffer(
objValueBuffer_ = fields.objValueBuffer;
regExpTable_ = fields.regExpTable;
regExpStorage_ = fields.regExpStorage;
cjsModuleOffset_ = fileHeader->cjsModuleOffset;
segmentID_ = fileHeader->segmentID;
cjsModuleTable_ = fields.cjsModuleTable;
cjsModuleTableStatic_ = fields.cjsModuleTableStatic;
}
Expand Down
3 changes: 1 addition & 2 deletions lib/BCGen/HBC/BytecodeDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ void BytecodeDisassembler::disassembleBytecodeFileHeader(raw_ostream &OS) {
OS << " String Kind Entry count: " << bcProvider_->getStringKinds().size()
<< "\n";
OS << " RegExp count: " << bcProvider_->getRegExpTable().size() << "\n";
OS << " CommonJS module offset: " << bcProvider_->getCJSModuleOffset()
<< "\n";
OS << " Segment ID: " << bcProvider_->getSegmentID() << "\n";
OS << " CommonJS module count: " << bcProvider_->getCJSModuleTable().size()
<< "\n";
OS << " CommonJS module count (static): "
Expand Down
6 changes: 1 addition & 5 deletions lib/BCGen/HBC/BytecodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,6 @@ void BytecodeModuleGenerator::addCJSModuleStatic(
uint32_t moduleID,
uint32_t functionID) {
assert(cjsModules_.empty() && "Unresolved modules must be in cjsModules_");
assert(
moduleID - cjsModuleOffset_ == cjsModulesStatic_.size() &&
"Module ID out of order in cjsModulesStatic_");
(void)moduleID;
cjsModulesStatic_.push_back({moduleID, functionID});
}

Expand Down Expand Up @@ -230,7 +226,7 @@ std::unique_ptr<BytecodeModule> BytecodeModuleGenerator::generate() {
std::move(arrayBuffer_),
std::move(objKeyBuffer_),
std::move(objValBuffer_),
cjsModuleOffset_,
segmentID_,
std::move(cjsModules_),
std::move(cjsModulesStatic_),
bytecodeOptions)};
Expand Down
2 changes: 1 addition & 1 deletion lib/BCGen/HBC/BytecodeProviderFromSrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ BCProviderFromSrc::BCProviderFromSrc(
objKeyBuffer_ = module_->getObjectBuffer().first;
objValueBuffer_ = module_->getObjectBuffer().second;

cjsModuleOffset_ = module_->getCJSModuleOffset();
segmentID_ = module_->getSegmentID();
cjsModuleTable_ = module_->getCJSModuleTable();
cjsModuleTableStatic_ = module_->getCJSModuleTableStatic();

Expand Down
2 changes: 1 addition & 1 deletion lib/BCGen/HBC/BytecodeStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void BytecodeSerializer::serialize(BytecodeModule &BM, const SHA1 &sourceHash) {
BM.getArrayBufferSize(),
BM.getObjectKeyBufferSize(),
BM.getObjectValueBufferSize(),
BM.getCJSModuleOffset(),
BM.getSegmentID(),
cjsModuleCount,
debugInfoOffset_,
BM.getBytecodeOptions()};
Expand Down
6 changes: 3 additions & 3 deletions lib/BCGen/HBC/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ void DebugInfo::disassembleLexicalData(llvh::raw_ostream &OS) const {
void DebugInfo::populateSourceMap(
SourceMapGenerator *sourceMap,
std::vector<uint32_t> &&functionOffsets,
uint32_t cjsModuleOffset) const {
uint32_t segmentID) const {
// Since our bytecode is not JavaScript, we interpret the source map in a
// creative way: each bytecode module is represented as a line, and bytecode
// addresses in the file are represented as column offsets.
Expand Down Expand Up @@ -355,8 +355,8 @@ void DebugInfo::populateSourceMap(
segments.push_back(segmentFor(*loc, offsetInFile, offset));
offset = fdid.getOffset();
}
sourceMap->addMappingsLine(std::move(segments), cjsModuleOffset);
sourceMap->addFunctionOffsets(std::move(functionOffsets), cjsModuleOffset);
sourceMap->addMappingsLine(std::move(segments), segmentID);
sourceMap->addFunctionOffsets(std::move(functionOffsets), segmentID);
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion lib/BCGen/HBC/HBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ std::unique_ptr<BytecodeModule> hbc::generateBytecodeModule(
BytecodeModuleGenerator BMGen(options);

if (range) {
BMGen.setCJSModuleOffset(range->first);
BMGen.setSegmentID(range->segment);
}

// Empty if all functions should be generated (i.e. bundle splitting was not
Expand Down
4 changes: 2 additions & 2 deletions lib/SourceMap/SourceMapGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ void SourceMapGenerator::outputAsJSONImpl(llvh::raw_ostream &OS) const {

void SourceMapGenerator::addFunctionOffsets(
std::vector<uint32_t> &&functionOffsets,
uint32_t cjsModuleOffset) {
uint32_t segmentID) {
assert(functionOffsets.size() > 0 && "functionOffsets can not be empty");
functionOffsets_[cjsModuleOffset] = std::move(functionOffsets);
functionOffsets_[segmentID] = std::move(functionOffsets);
}

} // namespace hermes
8 changes: 3 additions & 5 deletions lib/VM/JSError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,10 @@ ExecutionStatus JSError::constructStackTraceString(
// Code block was not in the cache, update the cache.
virtualOffset = sti.codeBlock->getVirtualOffset();
}
// Add 1 to the CJSModuleOffset to account for 1-based indexing of
// Add 1 to the SegmentID to account for 1-based indexing of
// symbolication tools.
lineNo = sti.codeBlock->getRuntimeModule()
->getBytecode()
->getCJSModuleOffset() +
1;
lineNo =
sti.codeBlock->getRuntimeModule()->getBytecode()->getSegmentID() + 1;
columnNo = sti.bytecodeOffset + virtualOffset;
isAddress = true;
}
Expand Down
9 changes: 4 additions & 5 deletions lib/VM/JSLib/HermesInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ static CallResult<HermesValue> getCodeBlockFileName(
/// * fileName (string)
/// * lineNumber (number) - 1 based
/// * columnNumber (number) - 1 based
/// * cjsModuleOffset (number) - 0 based
/// * segmentID (number) - 0 based
/// * virtualOffset (number) - 0 based
/// * isNative (boolean)
/// TypeError if func is not a function.
Expand Down Expand Up @@ -651,15 +651,14 @@ hermesInternalGetFunctionLocation(void *, Runtime *runtime, NativeArgs args) {
(void)res;
} else {
tmpHandle = HermesValue::encodeNumberValue(
codeBlock->getRuntimeModule()->getBytecode()->getCJSModuleOffset());
codeBlock->getRuntimeModule()->getBytecode()->getSegmentID());
res = JSObject::defineOwnProperty(
resultHandle,
runtime,
Predefined::getSymbolID(Predefined::cjsModuleOffset),
Predefined::getSymbolID(Predefined::segmentID),
DefinePropertyFlags::getDefaultNewPropertyFlags(),
tmpHandle);
assert(
res != ExecutionStatus::EXCEPTION && "Failed to set cjsModuleOffset");
assert(res != ExecutionStatus::EXCEPTION && "Failed to set segmentID");
(void)res;

tmpHandle = HermesValue::encodeNumberValue(codeBlock->getVirtualOffset());
Expand Down
4 changes: 2 additions & 2 deletions lib/VM/Profiler/CodeCoverageProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ CodeCoverageProfiler::getExecutedFunctions() {
}
for (auto &entry : coverageInfoIter->second.executedFuncBitsArrayMap) {
auto *bcProvider = entry.first->getBytecode();
const uint32_t moduleId = bcProvider->getCJSModuleOffset();
const uint32_t segmentID = bcProvider->getSegmentID();
const std::vector<bool> &moduleFuncBitsArray = entry.second;
for (uint32_t i = 0; i < moduleFuncBitsArray.size(); ++i) {
if (moduleFuncBitsArray[i]) {
const uint32_t funcVirtualOffset =
bcProvider->getVirtualOffsetForFunction(i);
funcInfos.emplace_back(moduleId, funcVirtualOffset);
funcInfos.emplace_back(segmentID, funcVirtualOffset);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/VM/Profiler/SamplingProfilerPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ uint32_t SamplingProfiler::walkRuntimeStack(
stackFrame.jsFrame.functionId) +
stackFrame.jsFrame.offset;

uint32_t moduleId = bcProvider->getCJSModuleOffset();
uint64_t frameAddress = ((uint64_t)moduleId << 32) + virtualOffset;
uint32_t segmentID = bcProvider->getSegmentID();
uint64_t frameAddress = ((uint64_t)segmentID << 32) + virtualOffset;
assert(
(frameAddress & kNativeFrameMask) == 0 &&
"Module id should take less than 32 bits");
Expand Down
5 changes: 2 additions & 3 deletions lib/VM/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1762,10 +1762,9 @@ void Runtime::crashWriteCallStack(JSONEmitter &json) {
.toStringRef(srcLocStorage));
}
}
uint32_t cjsModuleOffset =
runtimeModule->getBytecode()->getCJSModuleOffset();
uint32_t segmentID = runtimeModule->getBytecode()->getSegmentID();
llvh::StringRef sourceURL = runtimeModule->getSourceURL();
json.emitKeyValue("CJSModuleOffset", cjsModuleOffset);
json.emitKeyValue("SegmentID", segmentID);
json.emitKeyValue("SourceURL", sourceURL);
} else {
json.emitKeyValue("NativeCode", true);
Expand Down
Loading

0 comments on commit c57fde2

Please sign in to comment.