Skip to content

Commit

Permalink
Bug 1030446 - Build a list of code ranges and use this instead of Cal…
Browse files Browse the repository at this point in the history
…lSite for describing functions (r=dougc)

--HG--
extra : rebase_source : 6cb5cff2c3192f7d40315afe8007f7bd68549fec
  • Loading branch information
Luke Wagner committed Jun 25, 2014
1 parent 0028103 commit a3cf5fe
Show file tree
Hide file tree
Showing 21 changed files with 201 additions and 194 deletions.
43 changes: 19 additions & 24 deletions js/src/jit/AsmJS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "jsprf.h"
#include "prmjtime.h"

#include "assembler/assembler/MacroAssembler.h"
#include "frontend/Parser.h"
#include "jit/AsmJSLink.h"
#include "jit/AsmJSModule.h"
Expand Down Expand Up @@ -1409,9 +1408,6 @@ class MOZ_STACK_CLASS ModuleCompiler
return false;
return exits_.add(p, Move(exitDescriptor), *exitIndex);
}
bool addFunctionName(PropertyName *name, uint32_t *index) {
return module_->addFunctionName(name, index);
}

// Note a constraint on the minimum size of the heap. The heap size is
// constrained when linking to be at least the maximum of all such constraints.
Expand Down Expand Up @@ -1443,6 +1439,11 @@ class MOZ_STACK_CLASS ModuleCompiler
bool finishGeneratingFunction(Func &func, MIRGenerator &mir, CodeGenerator &codegen) {
JS_ASSERT(func.defined() && func.code()->bound());

uint32_t beginOffset = func.code()->offset();
uint32_t endOffset = masm_.currentOffset();
if (!module_->addFunctionCodeRange(func.name(), beginOffset, endOffset))
return false;

jit::IonScriptCounts *counts = codegen.extractScriptCounts();
if (counts && !module_->addFunctionCounts(counts)) {
js_delete(counts);
Expand Down Expand Up @@ -1480,15 +1481,19 @@ class MOZ_STACK_CLASS ModuleCompiler
module_->finishFunctionBodies(masm_.currentOffset());
}

void startGeneratingEntry(unsigned exportIndex) {
module_->exportedFunction(exportIndex).initCodeOffset(masm_.currentOffset());
}
bool finishGeneratingEntry(unsigned exportIndex) {
return module_->addEntryCodeRange(exportIndex, masm_.currentOffset());
}

void setInterpExitOffset(unsigned exitIndex) {
module_->exit(exitIndex).initInterpOffset(masm_.currentOffset());
}
void setIonExitOffset(unsigned exitIndex) {
module_->exit(exitIndex).initIonOffset(masm_.currentOffset());
}
void setEntryOffset(unsigned exportIndex) {
module_->exportedFunction(exportIndex).initCodeOffset(masm_.currentOffset());
}

void buildCompilationTimeReport(bool storedInCache, ScopedJSFreePtr<char> *out) {
ScopedJSFreePtr<char> slowFuns;
Expand Down Expand Up @@ -1808,7 +1813,6 @@ class FunctionCompiler
ModuleCompiler & m_;
LifoAlloc & lifo_;
ParseNode * fn_;
uint32_t functionNameIndex_;

LocalMap locals_;
VarInitializerVector varInitializers_;
Expand All @@ -1829,15 +1833,11 @@ class FunctionCompiler
LabeledBlockMap labeledBreaks_;
LabeledBlockMap labeledContinues_;

static const uint32_t NO_FUNCTION_NAME_INDEX = UINT32_MAX;
JS_STATIC_ASSERT(NO_FUNCTION_NAME_INDEX > CallSiteDesc::FUNCTION_NAME_INDEX_MAX);

public:
FunctionCompiler(ModuleCompiler &m, ParseNode *fn, LifoAlloc &lifo)
: m_(m),
lifo_(lifo),
fn_(fn),
functionNameIndex_(NO_FUNCTION_NAME_INDEX),
locals_(m.cx()),
varInitializers_(m.cx()),
alloc_(nullptr),
Expand Down Expand Up @@ -2279,12 +2279,7 @@ class FunctionCompiler
uint32_t line, column;
m_.tokenStream().srcCoords.lineNumAndColumnIndex(call.node_->pn_pos.begin, &line, &column);

if (functionNameIndex_ == NO_FUNCTION_NAME_INDEX) {
if (!m_.addFunctionName(FunctionName(fn_), &functionNameIndex_))
return false;
}

CallSiteDesc desc(line, column, functionNameIndex_);
CallSiteDesc desc(line, column);
MAsmJSCall *ins = MAsmJSCall::New(alloc(), desc, callee, call.regArgs_, returnType,
call.spIncrement_);
if (!ins)
Expand Down Expand Up @@ -5955,7 +5950,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
// PushRegsInMask(NonVolatileRegs).
masm.setFramePushed(0);

// See AsmJSFrameSize comment in Assembler-*.h.
// See AsmJSFrameSize comment in Assembler-shared.h.
#if defined(JS_CODEGEN_ARM)
masm.push(lr);
#endif // JS_CODEGEN_ARM
Expand Down Expand Up @@ -6030,7 +6025,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu

// Call into the real function.
AssertStackAlignment(masm);
masm.call(CallSiteDesc::Entry(), func.code());
masm.call(func.code());

// Pop the stack and recover the original 'argv' argument passed to the
// trampoline (which was pushed on the stack).
Expand Down Expand Up @@ -6214,7 +6209,7 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
m.setInterpExitOffset(exitIndex);
masm.setFramePushed(0);

// See AsmJSFrameSize comment in Assembler-*.h.
// See AsmJSFrameSize comment in Assembler-shared.h.
#if defined(JS_CODEGEN_ARM)
masm.push(lr);
#elif defined(JS_CODEGEN_MIPS)
Expand Down Expand Up @@ -6389,7 +6384,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
m.setIonExitOffset(exitIndex);
masm.setFramePushed(0);

// See AsmJSFrameSize comment in Assembler-*.h.
// See AsmJSFrameSize comment in Assembler-shared.h.
#if defined(JS_CODEGEN_ARM)
masm.push(lr);
#elif defined(JS_CODEGEN_MIPS)
Expand Down Expand Up @@ -6871,10 +6866,10 @@ static bool
GenerateStubs(ModuleCompiler &m)
{
for (unsigned i = 0; i < m.module().numExportedFunctions(); i++) {
m.setEntryOffset(i);
m.startGeneratingEntry(i);
if (!GenerateEntry(m, m.module().exportedFunction(i)))
return false;
if (m.masm().oom())
if (m.masm().oom() || !m.finishGeneratingEntry(i))
return false;
}

Expand Down
20 changes: 12 additions & 8 deletions js/src/jit/AsmJSFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using namespace js;
using namespace js::jit;

static uint8_t *
static void *
ReturnAddressFromFP(uint8_t *fp)
{
// In asm.js code, the "frame" consists of a single word: the saved
Expand All @@ -39,25 +39,29 @@ AsmJSFrameIterator::operator++()
}

void
AsmJSFrameIterator::settle(uint8_t *returnAddress)
AsmJSFrameIterator::settle(void *returnAddress)
{
callsite_ = module_->lookupCallSite(returnAddress);
JS_ASSERT(callsite_);
const AsmJSModule::CodeRange *codeRange = module_->lookupCodeRange(ReturnAddressFromFP(fp_));
JS_ASSERT(codeRange);
codeRange_ = codeRange;

if (callsite_->isEntry()) {
switch (codeRange->kind()) {
case AsmJSModule::CodeRange::Entry:
fp_ = nullptr;
JS_ASSERT(done());
return;
case AsmJSModule::CodeRange::Function:
callsite_ = module_->lookupCallSite(returnAddress);
JS_ASSERT(callsite_);
break;
}

JS_ASSERT(callsite_->isNormal());
}

JSAtom *
AsmJSFrameIterator::functionDisplayAtom() const
{
JS_ASSERT(!done());
return module_->functionName(callsite_->functionNameIndex());
return reinterpret_cast<const AsmJSModule::CodeRange*>(codeRange_)->functionName(*module_);
}

unsigned
Expand Down
6 changes: 5 additions & 1 deletion js/src/jit/AsmJSFrameIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ class AsmJSFrameIterator
const jit::CallSite *callsite_;
uint8_t *fp_;

void settle(uint8_t *returnAddress);
// Really, a const AsmJSModule::CodeRange*, but no forward declarations of
// nested classes, so use void* to avoid pulling in all of AsmJSModule.h.
const void *codeRange_;

void settle(void *returnAddress);

public:
explicit AsmJSFrameIterator() : module_(nullptr) {}
Expand Down
57 changes: 53 additions & 4 deletions js/src/jit/AsmJSModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ AsmJSModule::addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModu
exits_.sizeOfExcludingThis(mallocSizeOf) +
exports_.sizeOfExcludingThis(mallocSizeOf) +
callSites_.sizeOfExcludingThis(mallocSizeOf) +
codeRanges_.sizeOfExcludingThis(mallocSizeOf) +
functionNames_.sizeOfExcludingThis(mallocSizeOf) +
heapAccesses_.sizeOfExcludingThis(mallocSizeOf) +
functionCounts_.sizeOfExcludingThis(mallocSizeOf) +
Expand All @@ -189,11 +190,11 @@ struct CallSiteRetAddrOffset
};

const CallSite *
AsmJSModule::lookupCallSite(uint8_t *returnAddress) const
AsmJSModule::lookupCallSite(void *returnAddress) const
{
JS_ASSERT(isFinished());

uint32_t target = returnAddress - code_;
uint32_t target = ((uint8_t*)returnAddress) - code_;
size_t lowerBound = 0;
size_t upperBound = callSites_.length();

Expand All @@ -204,6 +205,45 @@ AsmJSModule::lookupCallSite(uint8_t *returnAddress) const
return &callSites_[match];
}

namespace js {

// Create an ordering on CodeRange and pc offsets suitable for BinarySearch.
// Stick these in the same namespace as AsmJSModule so that argument-dependent
// lookup will find it.
bool
operator==(size_t pcOffset, const AsmJSModule::CodeRange &rhs)
{
return pcOffset >= rhs.begin() && pcOffset < rhs.end();
}
bool
operator<=(const AsmJSModule::CodeRange &lhs, const AsmJSModule::CodeRange &rhs)
{
return lhs.begin() <= rhs.begin();
}
bool
operator<(size_t pcOffset, const AsmJSModule::CodeRange &rhs)
{
return pcOffset < rhs.begin();
}

} // namespace js

const AsmJSModule::CodeRange *
AsmJSModule::lookupCodeRange(void *pc) const
{
JS_ASSERT(isFinished());

uint32_t target = ((uint8_t*)pc) - code_;
size_t lowerBound = 0;
size_t upperBound = codeRanges_.length();

size_t match;
if (!BinarySearch(codeRanges_, lowerBound, upperBound, target, &match))
return nullptr;

return &codeRanges_[match];
}

struct HeapAccessOffset
{
const AsmJSHeapAccessVector &accesses;
Expand All @@ -214,12 +254,12 @@ struct HeapAccessOffset
};

const AsmJSHeapAccess *
AsmJSModule::lookupHeapAccess(uint8_t *pc) const
AsmJSModule::lookupHeapAccess(void *pc) const
{
JS_ASSERT(isFinished());
JS_ASSERT(containsPC(pc));

uint32_t target = pc - code_;
uint32_t target = ((uint8_t*)pc) - code_;
size_t lowerBound = 0;
size_t upperBound = heapAccesses_.length();

Expand Down Expand Up @@ -293,6 +333,11 @@ AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembl
CallSite &c = callSites_[i];
c.setReturnAddressOffset(masm.actualOffset(c.returnAddressOffset()));
}
for (size_t i = 0; i < codeRanges_.length(); i++) {
CodeRange &c = codeRanges_[i];
c.begin_ = masm.actualOffset(c.begin_);
c.end_ = masm.actualOffset(c.end_);
}
#endif
JS_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);

Expand Down Expand Up @@ -1084,6 +1129,7 @@ AsmJSModule::serializedSize() const
SerializedVectorSize(exits_) +
SerializedVectorSize(exports_) +
SerializedPodVectorSize(callSites_) +
SerializedPodVectorSize(codeRanges_) +
SerializedVectorSize(functionNames_) +
SerializedPodVectorSize(heapAccesses_) +
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
Expand All @@ -1104,6 +1150,7 @@ AsmJSModule::serialize(uint8_t *cursor) const
cursor = SerializeVector(cursor, exits_);
cursor = SerializeVector(cursor, exports_);
cursor = SerializePodVector(cursor, callSites_);
cursor = SerializePodVector(cursor, codeRanges_);
cursor = SerializeVector(cursor, functionNames_);
cursor = SerializePodVector(cursor, heapAccesses_);
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
Expand All @@ -1130,6 +1177,7 @@ AsmJSModule::deserialize(ExclusiveContext *cx, const uint8_t *cursor)
(cursor = DeserializeVector(cx, cursor, &exits_)) &&
(cursor = DeserializeVector(cx, cursor, &exports_)) &&
(cursor = DeserializePodVector(cx, cursor, &callSites_)) &&
(cursor = DeserializePodVector(cx, cursor, &codeRanges_)) &&
(cursor = DeserializeVector(cx, cursor, &functionNames_)) &&
(cursor = DeserializePodVector(cx, cursor, &heapAccesses_)) &&
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
Expand Down Expand Up @@ -1200,6 +1248,7 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
!CloneVector(cx, exits_, &out.exits_) ||
!CloneVector(cx, exports_, &out.exports_) ||
!ClonePodVector(cx, callSites_, &out.callSites_) ||
!ClonePodVector(cx, codeRanges_, &out.codeRanges_) ||
!CloneVector(cx, functionNames_, &out.functionNames_) ||
!ClonePodVector(cx, heapAccesses_, &out.heapAccesses_) ||
!staticLinkData_.clone(cx, &out.staticLinkData_))
Expand Down
Loading

0 comments on commit a3cf5fe

Please sign in to comment.