diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-17 18:14:30 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-17 18:14:30 -0800 |
commit | 1eac4681b17f405b784ba7709b19d5bfe3a631b1 (patch) | |
tree | d6c33ab6258c2027afad7568117b48cf0fca16a2 | |
parent | 3dd73e256fae2b0373ddb890f129942329fc6fa8 (diff) |
support reserved function pointers
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index a8530b1b1f..dd5e9ed0be 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -64,6 +64,11 @@ WarnOnUnaligned("emscripten-warn-unaligned", cl::desc("Warns about unaligned loads and stores (which can negatively affect performance)"), cl::init(false)); +static cl::opt<int> +ReservedFunctionPointers("emscripten-reserved-function-pointers", + cl::desc("Number of reserved slots in function tables for functions to be added at runtime (see emscripten RESERVED_FUNCTION_POINTERS option)"), + cl::init(0)); + extern "C" void LLVMInitializeJSBackendTarget() { // Register the target. RegisterTargetMachine<JSTargetMachine> X(TheJSBackendTarget); @@ -259,15 +264,21 @@ namespace { } return Ret; } + FunctionTable& ensureFunctionTable(const FunctionType *FT) { + FunctionTable &Table = FunctionTables[getFunctionSignature(FT)]; + unsigned MinSize = ReservedFunctionPointers ? 2*(ReservedFunctionPointers+1) : 1; // each reserved slot must be 2-aligned + while (Table.size() < MinSize) Table.push_back("0"); + return Table; + } unsigned getFunctionIndex(const Function *F) { const std::string &Name = getJSName(F); if (IndexedFunctions.find(Name) != IndexedFunctions.end()) return IndexedFunctions[Name]; std::string Sig = getFunctionSignature(F->getFunctionType(), &Name); - FunctionTable &Table = FunctionTables[Sig]; + FunctionTable& Table = ensureFunctionTable(F->getFunctionType()); // use alignment info to avoid unnecessary holes. This is not optimal though, // (1) depends on order of appearance, and (2) really just need align for &class::method, see test_polymorph unsigned Alignment = F->getAlignment() || 1; - while (Table.size() == 0 || Table.size() % Alignment) Table.push_back("0"); + while (Table.size() % Alignment) Table.push_back("0"); unsigned Index = Table.size(); Table.push_back(Name); IndexedFunctions[Name] = Index; @@ -280,9 +291,6 @@ namespace { return Index; } - void ensureFunctionTable(const FunctionType *F) { - FunctionTables[getFunctionSignature(F)]; - } // Return a constant we are about to write into a global as a numeric offset. If the // value is not known at compile time, emit a postSet to that location. unsigned getConstAsOffset(const Value *V, unsigned AbsoluteTarget) { |