mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 07:05:24 +00:00
If we extend a tree along a side exit that knew about fewer global slots that we have now in the tree, merge in the types for those additional slots from the entry map (450535).
This commit is contained in:
parent
a91faa3c28
commit
31d28b1621
@ -620,6 +620,19 @@ TypeMap::matches(TypeMap& other)
|
||||
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;
|
||||
}
|
||||
|
||||
TraceRecorder::TraceRecorder(JSContext* cx, GuardRecord* _anchor,
|
||||
Fragment* _fragment, unsigned ngslots, uint8* globalTypeMap, uint8* stackTypeMap)
|
||||
{
|
||||
@ -660,6 +673,23 @@ TraceRecorder::TraceRecorder(JSContext* cx, GuardRecord* _anchor,
|
||||
eos_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, eos)), "eos");
|
||||
eor_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, eor)), "eor");
|
||||
|
||||
/* 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. */
|
||||
unsigned length;
|
||||
if (ngslots < (length = treeInfo->globalTypeMap.length()))
|
||||
mergeTypeMaps(&globalTypeMap, &ngslots,
|
||||
treeInfo->globalTypeMap.data(), length,
|
||||
(uint8*)alloca(sizeof(uint8) * length));
|
||||
JS_ASSERT(ngslots == treeInfo->globalTypeMap.length());
|
||||
|
||||
/* read into registers all values on the stack and all globals we know so far */
|
||||
import(treeInfo, lirbuf->sp, ngslots, callDepth, globalTypeMap, stackTypeMap);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user