author | Hannes Verschore <hv1989@gmail.com> |
Tue, 15 Mar 2016 12:21:18 -0400 | |
changeset 288791 | a4ddac87ea0ce807686a6f18d74f25cb7a3edae8 |
parent 288790 | 2f9b5a3b2a90689a25ac91515803a0d17272583d |
child 288792 | 447ab351338571338f840028f4bc1efe035635f8 |
push id | 30089 |
push user | kwierso@gmail.com |
push date | Wed, 16 Mar 2016 00:26:08 +0000 |
treeherder | mozilla-central@7773387a9a2f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1250964 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/BaselineDebugModeOSR.h +++ b/js/src/jit/BaselineDebugModeOSR.h @@ -59,17 +59,17 @@ class DebugModeOSRVolatileStub : engine_(ICStubCompiler::Engine::Baseline), stub_(static_cast<T>(stub)), frame_(frame), pcOffset_(stub->icEntry()->pcOffset()) { } bool invalid() const { if (engine_ == ICStubCompiler::Engine::IonMonkey) - return false; + return stub_->invalid(); MOZ_ASSERT(!frame_->isHandlingException()); ICEntry& entry = frame_->script()->baselineScript()->icEntryFromPCOffset(pcOffset_); return stub_ != entry.fallbackStub(); } operator const T&() const { MOZ_ASSERT(!invalid()); return stub_; } T operator->() const { MOZ_ASSERT(!invalid()); return stub_; } T* address() { MOZ_ASSERT(!invalid()); return &stub_; }
--- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -1223,25 +1223,29 @@ IonScript::purgeOptimizedStubs(Zone* zon stub = stub->next(); continue; } prev = stub; stub = stub->next(); } + lastStub->toFallbackStub()->setInvalid(); + if (lastStub->isMonitoredFallback()) { // Monitor stubs can't make calls, so are always in the // optimized stub space. ICTypeMonitor_Fallback* lastMonStub = lastStub->toMonitoredFallbackStub()->fallbackMonitorStub(); lastMonStub->resetMonitorStubChain(zone); + lastMonStub->setInvalid(); } } else if (lastStub->isTypeMonitor_Fallback()) { lastStub->toTypeMonitor_Fallback()->resetMonitorStubChain(zone); + lastStub->toTypeMonitor_Fallback()->setInvalid(); } else { MOZ_ASSERT(lastStub->isTableSwitch()); } } #ifdef DEBUG // All remaining stubs must be allocated in the fallback space. for (size_t i = 0; i < numSharedStubs(); i++) {
--- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -926,16 +926,17 @@ SharedStubInfo::outerScript(JSContext* c { if (!outerScript_) { js::jit::JitActivationIterator iter(cx->runtime()); JitFrameIterator it(iter); MOZ_ASSERT(it.isExitFrame()); ++it; MOZ_ASSERT(it.isIonJS()); outerScript_ = it.script(); + MOZ_ASSERT(!it.ionScript()->invalidated()); } return outerScript_; } // // BinaryArith_Fallback // @@ -3051,31 +3052,32 @@ DoGetPropFallback(JSContext* cx, void* p // end up attaching a stub for the exact same access later. bool isTemporarilyUnoptimizable = false; RootedPropertyName name(cx, script->getName(pc)); // After the Genericstub was added, we should never reach the Fallbackstub again. MOZ_ASSERT(!stub->hasStub(ICStub::GetProp_Generic)); - if (stub->numOptimizedStubs() >= ICGetProp_Fallback::MAX_OPTIMIZED_STUBS) { + if (stub->numOptimizedStubs() >= ICGetProp_Fallback::MAX_OPTIMIZED_STUBS && !stub.invalid()) { // Discard all stubs in this IC and replace with generic getprop stub. for (ICStubIterator iter = stub->beginChain(); !iter.atEnd(); iter++) iter.unlink(cx); ICGetProp_Generic::Compiler compiler(cx, engine, stub->fallbackMonitorStub()->firstMonitorStub()); ICStub* newStub = compiler.getStub(compiler.getStubSpace(info.outerScript(cx))); if (!newStub) return false; stub->addNewStub(newStub); attached = true; } - if (!attached && !TryAttachNativeGetAccessorPropStub(cx, &info, stub, name, val, res, &attached, - &isTemporarilyUnoptimizable)) + if (!attached && !stub.invalid() && + !TryAttachNativeGetAccessorPropStub(cx, &info, stub, name, val, res, &attached, + &isTemporarilyUnoptimizable)) { return false; } if (!ComputeGetPropResult(cx, info.maybeFrame(), op, name, val, res)) return false; @@ -4165,16 +4167,17 @@ ICGetProp_Generic::Clone(JSContext* cx, } static bool DoGetPropGeneric(JSContext* cx, void* payload, ICGetProp_Generic* stub, MutableHandleValue val, MutableHandleValue res) { ICFallbackStub* fallback = stub->getChainFallback(); SharedStubInfo info(cx, payload, fallback->icEntry()); + MOZ_ASSERT(info.outerScript(cx)); HandleScript script = info.innerScript(); jsbytecode* pc = info.pc(); JSOp op = JSOp(*pc); RootedPropertyName name(cx, script->getName(pc)); return ComputeGetPropResult(cx, info.maybeFrame(), op, name, val, res); } typedef bool (*DoGetPropGenericFn)(JSContext*, void*, ICGetProp_Generic*, MutableHandleValue, MutableHandleValue); @@ -4772,17 +4775,17 @@ DoTypeMonitorFallback(JSContext* cx, voi TypeScript::SetArgument(cx, script, argument, value); } else { if (value.isMagic(JS_UNINITIALIZED_LEXICAL)) TypeScript::Monitor(cx, script, pc, TypeSet::UnknownType()); else TypeScript::Monitor(cx, script, pc, value); } - if (!stub->addMonitorStubForValue(cx, &info, value)) + if (!stub->invalid() && !stub->addMonitorStubForValue(cx, &info, value)) return false; // Copy input value to res. res.set(value); return true; } typedef bool (*DoTypeMonitorFallbackFn)(JSContext*, void*, ICTypeMonitor_Fallback*,
--- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -754,63 +754,75 @@ class ICFallbackStub : public ICStub protected: // Fallback stubs need these fields to easily add new stubs to // the linked list of stubs for an IC. // The IC entry for this linked list of stubs. ICEntry* icEntry_; // The number of stubs kept in the IC entry. - uint32_t numOptimizedStubs_; + uint32_t numOptimizedStubs_ : 31; + uint32_t invalid_ : 1; // A pointer to the location stub pointer that needs to be // changed to add a new "last" stub immediately before the fallback // stub. This'll start out pointing to the icEntry's "firstStub_" // field, and as new stubs are added, it'll point to the current // last stub's "next_" field. ICStub** lastStubPtrAddr_; ICFallbackStub(Kind kind, JitCode* stubCode) : ICStub(kind, ICStub::Fallback, stubCode), icEntry_(nullptr), numOptimizedStubs_(0), + invalid_(false), lastStubPtrAddr_(nullptr) {} ICFallbackStub(Kind kind, Trait trait, JitCode* stubCode) : ICStub(kind, trait, stubCode), icEntry_(nullptr), numOptimizedStubs_(0), + invalid_(false), lastStubPtrAddr_(nullptr) { MOZ_ASSERT(trait == ICStub::Fallback || trait == ICStub::MonitoredFallback); } public: inline ICEntry* icEntry() const { return icEntry_; } inline size_t numOptimizedStubs() const { return (size_t) numOptimizedStubs_; } + void setInvalid() { + invalid_ = 1; + } + + bool invalid() const { + return invalid_; + } + // The icEntry and lastStubPtrAddr_ fields can't be initialized when the stub is // created since the stub is created at compile time, and we won't know the IC entry // address until after compile when the JitScript is created. This method // allows these fields to be fixed up at that point. void fixupICEntry(ICEntry* icEntry) { MOZ_ASSERT(icEntry_ == nullptr); MOZ_ASSERT(lastStubPtrAddr_ == nullptr); icEntry_ = icEntry; lastStubPtrAddr_ = icEntry_->addressOfFirstStub(); } // Add a new stub to the IC chain terminated by this fallback stub. void addNewStub(ICStub* stub) { + MOZ_ASSERT(!invalid()); MOZ_ASSERT(*lastStubPtrAddr_ == this); MOZ_ASSERT(stub->next() == nullptr); stub->setNext(this); *lastStubPtrAddr_ = stub; lastStubPtrAddr_ = stub->addressOfNext(); numOptimizedStubs_++; } @@ -1267,17 +1279,19 @@ class ICTypeMonitor_Fallback : public IC ICStub* firstMonitorStub_; // Address of the last monitor stub's field pointing to this // fallback monitor stub. This will get updated when new // monitor stubs are created and added. ICStub** lastMonitorStubPtrAddr_; // Count of optimized type monitor stubs in this chain. - uint32_t numOptimizedMonitorStubs_ : 8; + uint32_t numOptimizedMonitorStubs_ : 7; + + uint32_t invalid_ : 1; // Whether this has a fallback stub referring to the IC entry. bool hasFallbackStub_ : 1; // Index of 'this' or argument which is being monitored, or BYTECODE_INDEX // if this is monitoring the types of values pushed at some bytecode. uint32_t argumentIndex_ : 23; @@ -1285,25 +1299,27 @@ class ICTypeMonitor_Fallback : public IC ICTypeMonitor_Fallback(JitCode* stubCode, ICMonitoredFallbackStub* mainFallbackStub, uint32_t argumentIndex) : ICStub(ICStub::TypeMonitor_Fallback, stubCode), mainFallbackStub_(mainFallbackStub), firstMonitorStub_(thisFromCtor()), lastMonitorStubPtrAddr_(nullptr), numOptimizedMonitorStubs_(0), + invalid_(false), hasFallbackStub_(mainFallbackStub != nullptr), argumentIndex_(argumentIndex) { } ICTypeMonitor_Fallback* thisFromCtor() { return this; } void addOptimizedMonitorStub(ICStub* stub) { + MOZ_ASSERT(!invalid()); stub->setNext(this); MOZ_ASSERT((lastMonitorStubPtrAddr_ != nullptr) == (numOptimizedMonitorStubs_ || !hasFallbackStub_)); if (lastMonitorStubPtrAddr_) *lastMonitorStubPtrAddr_ = stub; @@ -1347,16 +1363,24 @@ class ICTypeMonitor_Fallback : public IC static inline size_t offsetOfFirstMonitorStub() { return offsetof(ICTypeMonitor_Fallback, firstMonitorStub_); } inline uint32_t numOptimizedMonitorStubs() const { return numOptimizedMonitorStubs_; } + void setInvalid() { + invalid_ = 1; + } + + bool invalid() const { + return invalid_; + } + inline bool monitorsThis() const { return argumentIndex_ == 0; } inline bool monitorsArgument(uint32_t* pargument) const { if (argumentIndex_ > 0 && argumentIndex_ < BYTECODE_INDEX) { *pargument = argumentIndex_ - 1; return true;