mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Specialize trees to global types, so global type instability does not flush the cache (bug 469044, r=gal,brendan).
This commit is contained in:
parent
a2f947e2a1
commit
b3ff178462
@ -102,7 +102,6 @@ namespace nanojit {
|
||||
class TraceRecorder;
|
||||
extern "C++" { template<typename T> class Queue; }
|
||||
typedef Queue<uint16> SlotList;
|
||||
class TypeMap;
|
||||
|
||||
# define CLS(T) T*
|
||||
#else
|
||||
@ -127,7 +126,6 @@ typedef struct JSTraceMonitor {
|
||||
CLS(TraceRecorder) recorder;
|
||||
uint32 globalShape;
|
||||
CLS(SlotList) globalSlots;
|
||||
CLS(TypeMap) globalTypeMap;
|
||||
jsval *reservedDoublePool;
|
||||
jsval *reservedDoublePoolPtr;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,6 +66,9 @@ class Queue : public avmplus::GCObject {
|
||||
while (_max < size)
|
||||
_max <<= 1;
|
||||
_data = (T*)realloc(_data, _max * sizeof(T));
|
||||
#if defined(DEBUG)
|
||||
memset(&_data[_len], 0xcd, _max - _len);
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
Queue(unsigned max = 16) {
|
||||
@ -181,8 +184,10 @@ typedef Queue<uint16> SlotList;
|
||||
|
||||
class TypeMap : public Queue<uint8> {
|
||||
public:
|
||||
JS_REQUIRES_STACK void captureGlobalTypes(JSContext* cx, SlotList& slots);
|
||||
JS_REQUIRES_STACK void captureStackTypes(JSContext* cx, unsigned callDepth);
|
||||
JS_REQUIRES_STACK void captureTypes(JSContext* cx, SlotList& slots, unsigned callDepth);
|
||||
JS_REQUIRES_STACK void captureMissingGlobalTypes(JSContext* cx,
|
||||
SlotList& slots,
|
||||
unsigned stackSlots);
|
||||
bool matches(TypeMap& other) const;
|
||||
};
|
||||
|
||||
@ -210,11 +215,21 @@ struct VMSideExit : public nanojit::SideExit
|
||||
ExitType exitType;
|
||||
};
|
||||
|
||||
static inline uint8* getTypeMap(nanojit::SideExit* exit)
|
||||
static inline uint8* getStackTypeMap(nanojit::SideExit* exit)
|
||||
{
|
||||
return (uint8*)(((VMSideExit*)exit) + 1);
|
||||
}
|
||||
|
||||
static inline uint8* getGlobalTypeMap(nanojit::SideExit* exit)
|
||||
{
|
||||
return getStackTypeMap(exit) + ((VMSideExit*)exit)->numStackSlots;
|
||||
}
|
||||
|
||||
static inline uint8* getFullTypeMap(nanojit::SideExit* exit)
|
||||
{
|
||||
return getStackTypeMap(exit);
|
||||
}
|
||||
|
||||
struct InterpState
|
||||
{
|
||||
void* sp; /* native stack pointer, stack[0] is spbase[0] */
|
||||
@ -243,7 +258,8 @@ public:
|
||||
unsigned maxNativeStackSlots;
|
||||
ptrdiff_t nativeStackBase;
|
||||
unsigned maxCallDepth;
|
||||
TypeMap stackTypeMap;
|
||||
TypeMap typeMap;
|
||||
unsigned stackSlots;
|
||||
Queue<nanojit::Fragment*> dependentTrees;
|
||||
unsigned branchCount;
|
||||
Queue<VMSideExit*> sideExits;
|
||||
@ -253,6 +269,16 @@ public:
|
||||
fragment = _fragment;
|
||||
}
|
||||
~TreeInfo();
|
||||
|
||||
inline unsigned globalSlots() {
|
||||
return typeMap.length() - stackSlots;
|
||||
}
|
||||
inline uint8* globalTypeMap() {
|
||||
return typeMap.data() + stackSlots;
|
||||
}
|
||||
inline uint8* stackTypeMap() {
|
||||
return typeMap.data();
|
||||
}
|
||||
};
|
||||
|
||||
struct FrameInfo {
|
||||
@ -311,7 +337,6 @@ class TraceRecorder : public avmplus::GCObject {
|
||||
bool terminate;
|
||||
intptr_t terminate_ip_adj;
|
||||
nanojit::Fragment* outerToBlacklist;
|
||||
nanojit::Fragment* promotedPeer;
|
||||
TraceRecorder* nextRecorderToAbort;
|
||||
bool wasRootFragment;
|
||||
|
||||
@ -320,8 +345,8 @@ class TraceRecorder : public avmplus::GCObject {
|
||||
JS_REQUIRES_STACK ptrdiff_t nativeStackOffset(jsval* p) const;
|
||||
JS_REQUIRES_STACK void import(nanojit::LIns* base, ptrdiff_t offset, jsval* p, uint8& t,
|
||||
const char *prefix, uintN index, JSStackFrame *fp);
|
||||
JS_REQUIRES_STACK void import(TreeInfo* treeInfo, nanojit::LIns* sp, unsigned ngslots,
|
||||
unsigned callDepth, uint8* globalTypeMap, uint8* stackTypeMap);
|
||||
JS_REQUIRES_STACK void import(TreeInfo* treeInfo, nanojit::LIns* sp, unsigned stackSlots,
|
||||
unsigned callDepth, unsigned ngslots, uint8* typeMap);
|
||||
void trackNativeStackUse(unsigned slots);
|
||||
|
||||
JS_REQUIRES_STACK bool lazilyImportGlobalSlot(unsigned slot);
|
||||
@ -339,7 +364,8 @@ class TraceRecorder : public avmplus::GCObject {
|
||||
JS_REQUIRES_STACK bool checkType(jsval& v, uint8 t, jsval*& stage_val,
|
||||
nanojit::LIns*& stage_ins, unsigned& stage_count);
|
||||
JS_REQUIRES_STACK bool deduceTypeStability(nanojit::Fragment* root_peer,
|
||||
nanojit::Fragment** stable_peer, unsigned* demotes);
|
||||
nanojit::Fragment** stable_peer,
|
||||
bool& demote);
|
||||
|
||||
JS_REQUIRES_STACK jsval& argval(unsigned n) const;
|
||||
JS_REQUIRES_STACK jsval& varval(unsigned n) const;
|
||||
@ -444,7 +470,7 @@ class TraceRecorder : public avmplus::GCObject {
|
||||
public:
|
||||
JS_REQUIRES_STACK
|
||||
TraceRecorder(JSContext* cx, VMSideExit*, nanojit::Fragment*, TreeInfo*,
|
||||
unsigned ngslots, uint8* globalTypeMap, uint8* stackTypeMap,
|
||||
unsigned stackSlots, unsigned ngslots, uint8* typeMap,
|
||||
VMSideExit* expectedInnerExit, nanojit::Fragment* outerToBlacklist);
|
||||
~TraceRecorder();
|
||||
|
||||
@ -455,14 +481,12 @@ public:
|
||||
nanojit::Fragment* getFragment() const { return fragment; }
|
||||
JS_REQUIRES_STACK bool isLoopHeader(JSContext* cx) const;
|
||||
JS_REQUIRES_STACK void compile(nanojit::Fragmento* fragmento);
|
||||
JS_REQUIRES_STACK bool closeLoop(nanojit::Fragmento* fragmento, bool& demote,
|
||||
unsigned *demotes);
|
||||
JS_REQUIRES_STACK bool closeLoop(nanojit::Fragmento* fragmento, bool& demote);
|
||||
JS_REQUIRES_STACK void endLoop(nanojit::Fragmento* fragmento);
|
||||
JS_REQUIRES_STACK void joinEdgesToEntry(nanojit::Fragmento* fragmento,
|
||||
nanojit::Fragment* peer_root);
|
||||
void blacklist() { fragment->blacklist(); }
|
||||
JS_REQUIRES_STACK bool adjustCallerTypes(nanojit::Fragment* f, unsigned* demote_slots,
|
||||
bool& trash);
|
||||
JS_REQUIRES_STACK bool adjustCallerTypes(nanojit::Fragment* f);
|
||||
JS_REQUIRES_STACK nanojit::Fragment* findNestedCompatiblePeer(nanojit::Fragment* f,
|
||||
nanojit::Fragment** empty);
|
||||
JS_REQUIRES_STACK void prepareTreeCall(nanojit::Fragment* inner);
|
||||
@ -484,7 +508,6 @@ public:
|
||||
void deepAbort() { deepAborted = true; }
|
||||
bool wasDeepAborted() { return deepAborted; }
|
||||
bool walkedOutOfLoop() { return terminate; }
|
||||
void setPromotedPeer(nanojit::Fragment* peer) { promotedPeer = peer; }
|
||||
TreeInfo* getTreeInfo() { return treeInfo; }
|
||||
|
||||
#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
|
||||
|
@ -2435,11 +2435,11 @@ function testThinLoopDemote() {
|
||||
}
|
||||
testThinLoopDemote.expected = 100;
|
||||
testThinLoopDemote.jitstats = {
|
||||
recorderStarted: 3,
|
||||
recorderStarted: 2,
|
||||
recorderAborted: 0,
|
||||
traceCompleted: 1,
|
||||
traceTriggered: 0,
|
||||
unstableLoopVariable: 2
|
||||
traceCompleted: 2,
|
||||
traceTriggered: 1,
|
||||
unstableLoopVariable: 1
|
||||
};
|
||||
test(testThinLoopDemote);
|
||||
|
||||
@ -2482,11 +2482,11 @@ function testWeirdDateParse() {
|
||||
}
|
||||
testWeirdDateParse.expected = "11,17,2008,11,17,2008,11,17,2008,11,17,2008,11,17,2008";
|
||||
testWeirdDateParse.jitstats = {
|
||||
recorderStarted: 10,
|
||||
recorderStarted: 7,
|
||||
recorderAborted: 1,
|
||||
traceCompleted: 5,
|
||||
traceTriggered: 13,
|
||||
unstableLoopVariable: 6,
|
||||
traceCompleted: 6,
|
||||
traceTriggered: 14,
|
||||
unstableLoopVariable: 3,
|
||||
noCompatInnerTrees: 1
|
||||
};
|
||||
test(testWeirdDateParse);
|
||||
@ -3997,6 +3997,19 @@ function testStringResolve() {
|
||||
testStringResolve.expected = 3;
|
||||
test(testStringResolve);
|
||||
|
||||
//test no multitrees assert
|
||||
function testGlobalMultitrees1() {
|
||||
(function() {
|
||||
for (var j = 0; j < 4; ++j) {
|
||||
for each (e in ['A', 1, 'A']) {
|
||||
}
|
||||
}
|
||||
})();
|
||||
return true;
|
||||
}
|
||||
testGlobalMultitrees1.expected = true;
|
||||
test(testGlobalMultitrees1);
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* _____ _ _ _____ ______ _____ _______ *
|
||||
|
Loading…
Reference in New Issue
Block a user