This commit is contained in:
Andreas Gal 2009-06-04 20:12:44 -07:00
commit 3882ad59b6
2 changed files with 33 additions and 20 deletions

View File

@ -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());
/*

View File

@ -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,