Skip to content

Commit

Permalink
Reuse debug info cache between HBCISel calls
Browse files Browse the repository at this point in the history
Summary:
When the sourceMapURL is huge (due to being a literal base64-encoded
URL-embedded sourcemap), it actually makes sense to reuse the debug
cache between functions.

In one measured case, this reduced runtime from 55s to 3s

Reviewed By: avp

Differential Revision: D23123584

fbshipit-source-id: 86eb770c4ba41c71db165a9a7f8fce39b4e74315
  • Loading branch information
willholen authored and facebook-github-bot committed Aug 14, 2020
1 parent b6a65cd commit 3bd7ce9
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
28 changes: 20 additions & 8 deletions include/hermes/BCGen/HBC/ISel.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
namespace hermes {
namespace hbc {

// Looking up filename/sourcemap id for each instruction is pretty slow,
// and it's almost always from the same bufId every time. Cache the previous
// result in this struct.
struct HBCISelDebugCache {
unsigned currentBufId = -1;
unsigned currentFilenameId;
unsigned currentSourceMappingUrlId;
};

class HBCISel {
struct Relocation {
enum RelocationType {
Expand Down Expand Up @@ -159,14 +168,7 @@ class HBCISel {
uint8_t acquirePropertyReadCacheIndex(unsigned id);
uint8_t acquirePropertyWriteCacheIndex(unsigned id);

// Looking up filename/sourcemap id for each instruction is pretty slow,
// and it's almost always from the same bufId every time. Cache the previous
// result here, to reuse it when possible.
struct {
unsigned currentBufId;
unsigned currentFilenameId;
unsigned currentSourceMappingUrlId;
} debugIdCache_;
HBCISelDebugCache debugIdCache_;

public:
/// C'tor.
Expand Down Expand Up @@ -201,6 +203,16 @@ class HBCISel {

/// Generate the bytecode stream for the function.
void generate(SourceMapGenerator *outSourceMap);

/// Get the current debug cache, to allow pre-populating another HBCISel in
/// the same module.
HBCISelDebugCache getDebugCache() {
return debugIdCache_;
}
/// Populate the debug cache with data from a previous function.
void populateDebugCache(HBCISelDebugCache cache) {
debugIdCache_ = cache;
}
};

} // namespace hbc
Expand Down
6 changes: 6 additions & 0 deletions lib/BCGen/HBC/HBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ std::unique_ptr<BytecodeModule> hbc::generateBytecodeModule(

// Construct the relative function scope depth map.
FunctionScopeAnalysis scopeAnalysis{lexicalTopLevel};

// Allow reusing the debug cache between functions
HBCISelDebugCache debugCache;

// Bytecode generation for each function.
for (auto &F : *M) {
if (!shouldGenerate(&F)) {
Expand Down Expand Up @@ -295,7 +299,9 @@ std::unique_ptr<BytecodeModule> hbc::generateBytecodeModule(
funcGen =
BytecodeFunctionGenerator::create(BMGen, RA.getMaxRegisterUsage());
HBCISel hbciSel(&F, funcGen.get(), RA, scopeAnalysis);
hbciSel.populateDebugCache(debugCache);
hbciSel.generate(sourceMapGen);
debugCache = hbciSel.getDebugCache();
}

BMGen.setFunctionGenerator(&F, std::move(funcGen));
Expand Down
1 change: 0 additions & 1 deletion lib/BCGen/HBC/ISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ void HBCISel::addDebugSourceLocationInfo(SourceMapGenerator *outSourceMap) {
IRBuilder builder(F_);

DebugSourceLocation info{};
debugIdCache_.currentBufId = (unsigned)-1;

bool hasDebugInfo = false;
for (auto &reloc : relocations_) {
Expand Down

0 comments on commit 3bd7ce9

Please sign in to comment.