This commit is contained in:
Robert Sayre 2009-06-04 23:16:04 -04:00
Родитель e98175be6f 1199bcd4cf
Коммит bc58285df7
2 изменённых файлов: 34 добавлений и 24 удалений

Просмотреть файл

@ -1308,6 +1308,19 @@ TypeMap::matches(TypeMap& other) const
return !memcmp(data(), other.data(), length());
}
/* Use the provided storage area to create a new type map that contains the partial type map
with the rest of it filled up from the complete type map. */
static void
mergeTypeMaps(uint8** partial, unsigned* plength, uint8* complete, unsigned clength, uint8* mem)
{
unsigned l = *plength;
JS_ASSERT(l < clength);
memcpy(mem, *partial, l * sizeof(uint8));
memcpy(mem + l, complete + l, (clength - l) * sizeof(uint8));
*partial = mem;
*plength = clength;
}
/* Specializes a tree to any missing globals, including any dependent trees. */
static JS_REQUIRES_STACK void
specializeTreesToMissingGlobals(JSContext* cx, TreeInfo* root)
@ -2077,16 +2090,29 @@ JS_REQUIRES_STACK void
TraceRecorder::import(TreeInfo* treeInfo, LIns* sp, unsigned stackSlots, unsigned ngslots,
unsigned callDepth, uint8* typeMap)
{
/* If we get a partial list that doesn't have all the types (i.e. recording from a side
exit that was recorded but we added more global slots later), merge the missing types
from the entry type map. This is safe because at the loop edge we verify that we
have compatible types for all globals (entry type and loop edge type match). While
a different trace of the tree might have had a guard with a different type map for
these slots we just filled in here (the guard we continue from didn't know about them),
since we didn't take that particular guard the only way we could have ended up here
is if that other trace had at its end a compatible type distribution with the entry
map. Since thats exactly what we used to fill in the types our current side exit
didn't provide, this is always safe to do. */
uint8* globalTypeMap = typeMap + stackSlots;
unsigned length = treeInfo->nGlobalTypes();
/*
* If we get a partial list that doesn't have all the types, capture the missing types
* from the current environment.
* This is potentially the typemap of the side exit and thus shorter than the tree's
* global type map.
*/
TypeMap fullTypeMap(typeMap, stackSlots + ngslots);
if (ngslots < treeInfo->globalSlots->length()) {
fullTypeMap.captureMissingGlobalTypes(cx, *treeInfo->globalSlots, stackSlots);
ngslots = treeInfo->globalSlots->length();
if (ngslots < length) {
mergeTypeMaps(&globalTypeMap/*out param*/, &ngslots/*out param*/,
treeInfo->globalTypeMap(), length,
(uint8*)alloca(sizeof(uint8) * length));
}
uint8* globalTypeMap = fullTypeMap.data() + stackSlots;
JS_ASSERT(ngslots == treeInfo->nGlobalTypes());
/*
@ -2291,11 +2317,8 @@ TraceRecorder::adjustCallerTypes(Fragment* f)
FORALL_GLOBAL_SLOTS(cx, ngslots, gslots,
LIns* i = get(vp);
bool isPromote = isPromoteInt(i);
if (isPromote && *m == JSVAL_DOUBLE) {
if (isPromote && *m == JSVAL_DOUBLE)
lir->insStorei(get(vp), lirbuf->state, nativeGlobalOffset(vp));
/* Aggressively undo speculation so the inner tree will compile if this fails. */
oracle.markGlobalSlotUndemotable(cx, gslots[n]);
}
JS_ASSERT(!(!isPromote && *m == JSVAL_INT));
++m;
);

Просмотреть файл

@ -76,13 +76,6 @@ public:
this->_data = (T*)malloc(max * sizeof(T));
}
Queue(T* data, unsigned length) {
this->_max =
this->_len = length;
this->_data = (T*)malloc(length * sizeof(T));
memcpy(this->_data, data, length);
}
~Queue() {
free(_data);
}
@ -196,12 +189,6 @@ typedef Queue<uint16> SlotList;
class TypeMap : public Queue<uint8> {
public:
TypeMap() : Queue<uint8>() {
}
TypeMap(uint8* partial, unsigned length) : Queue<uint8>(partial, length) {
}
JS_REQUIRES_STACK void captureTypes(JSContext* cx, SlotList& slots, unsigned callDepth);
JS_REQUIRES_STACK void captureMissingGlobalTypes(JSContext* cx,
SlotList& slots,