зеркало из https://github.com/mozilla/gecko-dev.git
Bug 864928 - Remove ScriptAnalysis::analyzeTypes, r=jandem.
This commit is contained in:
Родитель
a8d96b359f
Коммит
3a92a6a72f
|
@ -1787,88 +1787,6 @@ ScriptAnalysis::needsArgsObj(JSContext *cx)
|
||||||
return needsArgsObj(cx, seen, SSAValue::PushedValue(pcOff, 0));
|
return needsArgsObj(cx, seen, SSAValue::PushedValue(pcOff, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
CrossSSAValue
|
|
||||||
CrossScriptSSA::foldValue(const CrossSSAValue &cv)
|
|
||||||
{
|
|
||||||
const Frame &frame = getFrame(cv.frame);
|
|
||||||
const SSAValue &v = cv.v;
|
|
||||||
|
|
||||||
JSScript *parentScript = NULL;
|
|
||||||
ScriptAnalysis *parentAnalysis = NULL;
|
|
||||||
if (frame.parent != INVALID_FRAME) {
|
|
||||||
parentScript = getFrame(frame.parent).script;
|
|
||||||
parentAnalysis = parentScript->analysis();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v.kind() == SSAValue::VAR && v.varInitial() && parentScript) {
|
|
||||||
uint32_t slot = v.varSlot();
|
|
||||||
if (slot >= ArgSlot(0) && slot < LocalSlot(frame.script, 0)) {
|
|
||||||
uint32_t argc = GET_ARGC(frame.parentpc);
|
|
||||||
SSAValue argv = parentAnalysis->poppedValue(frame.parentpc, argc - 1 - (slot - ArgSlot(0)));
|
|
||||||
return foldValue(CrossSSAValue(frame.parent, argv));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v.kind() == SSAValue::PUSHED) {
|
|
||||||
jsbytecode *pc = frame.script->code + v.pushedOffset();
|
|
||||||
|
|
||||||
switch (JSOp(*pc)) {
|
|
||||||
case JSOP_THIS:
|
|
||||||
if (parentScript) {
|
|
||||||
uint32_t argc = GET_ARGC(frame.parentpc);
|
|
||||||
SSAValue thisv = parentAnalysis->poppedValue(frame.parentpc, argc);
|
|
||||||
return foldValue(CrossSSAValue(frame.parent, thisv));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSOP_CALL: {
|
|
||||||
/*
|
|
||||||
* If there is a single inline callee with a single return site,
|
|
||||||
* propagate back to that.
|
|
||||||
*/
|
|
||||||
JSScript *callee = NULL;
|
|
||||||
uint32_t calleeFrame = INVALID_FRAME;
|
|
||||||
for (unsigned i = 0; i < numFrames(); i++) {
|
|
||||||
if (iterFrame(i).parent == cv.frame && iterFrame(i).parentpc == pc) {
|
|
||||||
if (callee)
|
|
||||||
return cv; /* Multiple callees */
|
|
||||||
callee = iterFrame(i).script;
|
|
||||||
calleeFrame = iterFrame(i).index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (callee && callee->analysis()->numReturnSites() == 1) {
|
|
||||||
ScriptAnalysis *analysis = callee->analysis();
|
|
||||||
uint32_t offset = 0;
|
|
||||||
while (offset < callee->length) {
|
|
||||||
jsbytecode *pc = callee->code + offset;
|
|
||||||
if (analysis->maybeCode(pc) && JSOp(*pc) == JSOP_RETURN)
|
|
||||||
return foldValue(CrossSSAValue(calleeFrame, analysis->poppedValue(pc, 0)));
|
|
||||||
offset += GetBytecodeLength(pc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case JSOP_TOID: {
|
|
||||||
/*
|
|
||||||
* TOID acts as identity for integers, so to get better precision
|
|
||||||
* we should propagate its popped values forward if it acted as
|
|
||||||
* identity.
|
|
||||||
*/
|
|
||||||
ScriptAnalysis *analysis = frame.script->analysis();
|
|
||||||
SSAValue toidv = analysis->poppedValue(pc, 0);
|
|
||||||
if (analysis->getValueTypes(toidv)->getKnownTypeTag() == JSVAL_TYPE_INT32)
|
|
||||||
return foldValue(CrossSSAValue(cv.frame, toidv));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cv;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -78,15 +78,6 @@ class Bytecode
|
||||||
/* Whether this is a catch/finally entry point. */
|
/* Whether this is a catch/finally entry point. */
|
||||||
bool exceptionEntry : 1;
|
bool exceptionEntry : 1;
|
||||||
|
|
||||||
/*
|
|
||||||
* Side effects of this bytecode were not determined by type inference.
|
|
||||||
* Either a property set with unknown lvalue, or call with unknown callee.
|
|
||||||
*/
|
|
||||||
bool monitoredTypes : 1;
|
|
||||||
|
|
||||||
/* Call whose result should be monitored. */
|
|
||||||
bool monitoredTypesReturn : 1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dynamically observed state about the execution of this opcode. These are
|
* Dynamically observed state about the execution of this opcode. These are
|
||||||
* hints about the script for use during compilation.
|
* hints about the script for use during compilation.
|
||||||
|
@ -129,14 +120,6 @@ class Bytecode
|
||||||
*/
|
*/
|
||||||
Vector<SlotValue> *pendingValues;
|
Vector<SlotValue> *pendingValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* --------- Type inference --------- */
|
|
||||||
|
|
||||||
/* Types for all values pushed by this bytecode. */
|
|
||||||
types::StackTypeSet *pushedTypes;
|
|
||||||
|
|
||||||
/* Any type barriers in place at this bytecode. */
|
|
||||||
types::TypeBarrier *typeBarriers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -471,7 +454,6 @@ class SSAValue
|
||||||
uint32_t phiSlot() const;
|
uint32_t phiSlot() const;
|
||||||
uint32_t phiLength() const;
|
uint32_t phiLength() const;
|
||||||
const SSAValue &phiValue(uint32_t i) const;
|
const SSAValue &phiValue(uint32_t i) const;
|
||||||
types::TypeSet *phiTypes() const;
|
|
||||||
|
|
||||||
/* Offset at which this phi node was created. */
|
/* Offset at which this phi node was created. */
|
||||||
uint32_t phiOffset() const {
|
uint32_t phiOffset() const {
|
||||||
|
@ -571,7 +553,6 @@ class SSAValue
|
||||||
*/
|
*/
|
||||||
struct SSAPhiNode
|
struct SSAPhiNode
|
||||||
{
|
{
|
||||||
types::StackTypeSet types;
|
|
||||||
uint32_t slot;
|
uint32_t slot;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
SSAValue *options;
|
SSAValue *options;
|
||||||
|
@ -599,13 +580,6 @@ SSAValue::phiValue(uint32_t i) const
|
||||||
return u.phi.node->options[i];
|
return u.phi.node->options[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline types::TypeSet *
|
|
||||||
SSAValue::phiTypes() const
|
|
||||||
{
|
|
||||||
JS_ASSERT(kind() == PHI);
|
|
||||||
return &u.phi.node->types;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SSAUseChain
|
class SSAUseChain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -654,7 +628,6 @@ class ScriptAnalysis
|
||||||
bool ranBytecode_;
|
bool ranBytecode_;
|
||||||
bool ranSSA_;
|
bool ranSSA_;
|
||||||
bool ranLifetimes_;
|
bool ranLifetimes_;
|
||||||
bool ranInference_;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* Whether the compartment was in debug mode when we performed the analysis. */
|
/* Whether the compartment was in debug mode when we performed the analysis. */
|
||||||
|
@ -689,15 +662,10 @@ class ScriptAnalysis
|
||||||
bool ranBytecode() { return ranBytecode_; }
|
bool ranBytecode() { return ranBytecode_; }
|
||||||
bool ranSSA() { return ranSSA_; }
|
bool ranSSA() { return ranSSA_; }
|
||||||
bool ranLifetimes() { return ranLifetimes_; }
|
bool ranLifetimes() { return ranLifetimes_; }
|
||||||
bool ranInference() { return ranInference_; }
|
|
||||||
|
|
||||||
void analyzeBytecode(JSContext *cx);
|
void analyzeBytecode(JSContext *cx);
|
||||||
void analyzeSSA(JSContext *cx);
|
void analyzeSSA(JSContext *cx);
|
||||||
void analyzeLifetimes(JSContext *cx);
|
void analyzeLifetimes(JSContext *cx);
|
||||||
void analyzeTypes(JSContext *cx);
|
|
||||||
|
|
||||||
/* Analyze the effect of invoking 'new' on script. */
|
|
||||||
void analyzeTypesNew(JSContext *cx);
|
|
||||||
|
|
||||||
bool OOM() const { return outOfMemory; }
|
bool OOM() const { return outOfMemory; }
|
||||||
bool failed() const { return hadFailure; }
|
bool failed() const { return hadFailure; }
|
||||||
|
@ -760,45 +728,6 @@ class ScriptAnalysis
|
||||||
}
|
}
|
||||||
const SlotValue *newValues(const jsbytecode *pc) { return newValues(pc - script_->code); }
|
const SlotValue *newValues(const jsbytecode *pc) { return newValues(pc - script_->code); }
|
||||||
|
|
||||||
inline types::StackTypeSet *pushedTypes(uint32_t offset, uint32_t which = 0);
|
|
||||||
inline types::StackTypeSet *pushedTypes(const jsbytecode *pc, uint32_t which);
|
|
||||||
|
|
||||||
bool hasPushedTypes(const jsbytecode *pc) { return getCode(pc).pushedTypes != NULL; }
|
|
||||||
|
|
||||||
types::TypeBarrier *typeBarriers(JSContext *cx, uint32_t offset) {
|
|
||||||
if (getCode(offset).typeBarriers)
|
|
||||||
pruneTypeBarriers(cx, offset);
|
|
||||||
return getCode(offset).typeBarriers;
|
|
||||||
}
|
|
||||||
types::TypeBarrier *typeBarriers(JSContext *cx, const jsbytecode *pc) {
|
|
||||||
return typeBarriers(cx, pc - script_->code);
|
|
||||||
}
|
|
||||||
void addTypeBarrier(JSContext *cx, const jsbytecode *pc,
|
|
||||||
types::TypeSet *target, types::Type type);
|
|
||||||
void addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc,
|
|
||||||
types::TypeSet *target,
|
|
||||||
HandleObject singleton, HandleId singletonId);
|
|
||||||
|
|
||||||
/* Remove obsolete type barriers at the given offset. */
|
|
||||||
void pruneTypeBarriers(JSContext *cx, uint32_t offset);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove still-active type barriers at the given offset. If 'all' is set,
|
|
||||||
* then all barriers are removed, otherwise only those deemed excessive
|
|
||||||
* are removed.
|
|
||||||
*/
|
|
||||||
void breakTypeBarriers(JSContext *cx, uint32_t offset, bool all);
|
|
||||||
|
|
||||||
/* Break all type barriers used in computing v. */
|
|
||||||
void breakTypeBarriersSSA(JSContext *cx, const SSAValue &v);
|
|
||||||
|
|
||||||
inline void addPushedType(JSContext *cx, uint32_t offset, uint32_t which, types::Type type);
|
|
||||||
|
|
||||||
inline types::StackTypeSet *getValueTypes(const SSAValue &v);
|
|
||||||
|
|
||||||
inline types::StackTypeSet *poppedTypes(uint32_t offset, uint32_t which);
|
|
||||||
inline types::StackTypeSet *poppedTypes(const jsbytecode *pc, uint32_t which);
|
|
||||||
|
|
||||||
bool trackUseChain(const SSAValue &v) {
|
bool trackUseChain(const SSAValue &v) {
|
||||||
JS_ASSERT_IF(v.kind() == SSAValue::VAR, trackSlot(v.varSlot()));
|
JS_ASSERT_IF(v.kind() == SSAValue::VAR, trackSlot(v.varSlot()));
|
||||||
return v.kind() != SSAValue::EMPTY &&
|
return v.kind() != SSAValue::EMPTY &&
|
||||||
|
@ -912,9 +841,6 @@ class ScriptAnalysis
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Type inference helpers */
|
|
||||||
bool analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferenceState &state);
|
|
||||||
|
|
||||||
typedef Vector<SSAValue, 16> SeenVector;
|
typedef Vector<SSAValue, 16> SeenVector;
|
||||||
bool needsArgsObj(JSContext *cx, SeenVector &seen, const SSAValue &v);
|
bool needsArgsObj(JSContext *cx, SeenVector &seen, const SSAValue &v);
|
||||||
bool needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use);
|
bool needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use);
|
||||||
|
@ -928,84 +854,6 @@ class ScriptAnalysis
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SSA value as used by CrossScriptSSA, identifies the frame it came from. */
|
|
||||||
struct CrossSSAValue
|
|
||||||
{
|
|
||||||
unsigned frame;
|
|
||||||
SSAValue v;
|
|
||||||
CrossSSAValue(unsigned frame, const SSAValue &v) : frame(frame), v(v) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Analysis for managing SSA values from multiple call stack frames. These are
|
|
||||||
* created by the backend compiler when inlining functions, and allow for
|
|
||||||
* values to be tracked as they flow into or out of the inlined frames.
|
|
||||||
*/
|
|
||||||
class CrossScriptSSA
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
static const uint32_t OUTER_FRAME = UINT32_MAX;
|
|
||||||
static const unsigned INVALID_FRAME = uint32_t(-2);
|
|
||||||
|
|
||||||
struct Frame {
|
|
||||||
uint32_t index;
|
|
||||||
JSScript *script;
|
|
||||||
uint32_t depth; /* Distance from outer frame to this frame, in sizeof(Value) */
|
|
||||||
uint32_t parent;
|
|
||||||
jsbytecode *parentpc;
|
|
||||||
|
|
||||||
Frame(uint32_t index, JSScript *script, uint32_t depth, uint32_t parent,
|
|
||||||
jsbytecode *parentpc)
|
|
||||||
: index(index), script(script), depth(depth), parent(parent), parentpc(parentpc)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
const Frame &getFrame(uint32_t index) {
|
|
||||||
if (index == OUTER_FRAME)
|
|
||||||
return outerFrame;
|
|
||||||
return inlineFrames[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned numFrames() { return 1 + inlineFrames.length(); }
|
|
||||||
const Frame &iterFrame(unsigned i) {
|
|
||||||
if (i == 0)
|
|
||||||
return outerFrame;
|
|
||||||
return inlineFrames[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
JSScript *outerScript() { return outerFrame.script; }
|
|
||||||
|
|
||||||
/* Total length of scripts preceding a frame. */
|
|
||||||
size_t frameLength(uint32_t index) {
|
|
||||||
if (index == OUTER_FRAME)
|
|
||||||
return 0;
|
|
||||||
size_t res = outerFrame.script->length;
|
|
||||||
for (unsigned i = 0; i < index; i++)
|
|
||||||
res += inlineFrames[i].script->length;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline types::StackTypeSet *getValueTypes(const CrossSSAValue &cv);
|
|
||||||
|
|
||||||
bool addInlineFrame(JSScript *script, uint32_t depth, uint32_t parent,
|
|
||||||
jsbytecode *parentpc)
|
|
||||||
{
|
|
||||||
uint32_t index = inlineFrames.length();
|
|
||||||
return inlineFrames.append(Frame(index, script, depth, parent, parentpc));
|
|
||||||
}
|
|
||||||
|
|
||||||
CrossScriptSSA(JSContext *cx, JSScript *outer)
|
|
||||||
: outerFrame(OUTER_FRAME, outer, 0, INVALID_FRAME, NULL), inlineFrames(cx)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CrossSSAValue foldValue(const CrossSSAValue &cv);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Frame outerFrame;
|
|
||||||
Vector<Frame> inlineFrames;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
|
void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,64 +29,6 @@ ScriptAnalysis::poppedValue(const jsbytecode *pc, uint32_t which)
|
||||||
return poppedValue(pc - script_->code, which);
|
return poppedValue(pc - script_->code, which);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
ScriptAnalysis::pushedTypes(uint32_t offset, uint32_t which)
|
|
||||||
{
|
|
||||||
JS_ASSERT(offset < script_->length);
|
|
||||||
JS_ASSERT(which < GetDefCount(script_, offset) +
|
|
||||||
(ExtendedDef(script_->code + offset) ? 1 : 0));
|
|
||||||
types::StackTypeSet *array = getCode(offset).pushedTypes;
|
|
||||||
JS_ASSERT(array);
|
|
||||||
return array + which;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
ScriptAnalysis::pushedTypes(const jsbytecode *pc, uint32_t which)
|
|
||||||
{
|
|
||||||
return pushedTypes(pc - script_->code, which);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
ScriptAnalysis::getValueTypes(const SSAValue &v)
|
|
||||||
{
|
|
||||||
switch (v.kind()) {
|
|
||||||
case SSAValue::PUSHED:
|
|
||||||
return pushedTypes(v.pushedOffset(), v.pushedIndex());
|
|
||||||
case SSAValue::VAR:
|
|
||||||
JS_ASSERT(!slotEscapes(v.varSlot()));
|
|
||||||
if (v.varInitial()) {
|
|
||||||
if (v.varSlot() < LocalSlot(script_, 0))
|
|
||||||
return types::TypeScript::SlotTypes(script_, v.varSlot());
|
|
||||||
return undefinedTypeSet;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Results of intermediate assignments have the same type as
|
|
||||||
* the first type pushed by the assignment op. Note that this
|
|
||||||
* may not be the exact same value as was pushed, due to
|
|
||||||
* post-inc/dec ops.
|
|
||||||
*/
|
|
||||||
return pushedTypes(v.varOffset(), 0);
|
|
||||||
}
|
|
||||||
case SSAValue::PHI:
|
|
||||||
return &v.phiNode()->types;
|
|
||||||
default:
|
|
||||||
/* Cannot compute types for empty SSA values. */
|
|
||||||
MOZ_ASSUME_UNREACHABLE("Bad SSA value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
ScriptAnalysis::poppedTypes(uint32_t offset, uint32_t which)
|
|
||||||
{
|
|
||||||
return getValueTypes(poppedValue(offset, which));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
ScriptAnalysis::poppedTypes(const jsbytecode *pc, uint32_t which)
|
|
||||||
{
|
|
||||||
return getValueTypes(poppedValue(pc, which));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SSAUseChain *&
|
inline SSAUseChain *&
|
||||||
ScriptAnalysis::useChain(const SSAValue &v)
|
ScriptAnalysis::useChain(const SSAValue &v)
|
||||||
{
|
{
|
||||||
|
@ -107,12 +49,6 @@ ScriptAnalysis::getCallPC(jsbytecode *pc)
|
||||||
return script_->code + uses->offset;
|
return script_->code + uses->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline types::StackTypeSet *
|
|
||||||
CrossScriptSSA::getValueTypes(const CrossSSAValue &cv)
|
|
||||||
{
|
|
||||||
return getFrame(cv.frame).script->analysis()->getValueTypes(cv.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace analyze */
|
} /* namespace analyze */
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
|
|
2104
js/src/jsinfer.cpp
2104
js/src/jsinfer.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -571,22 +571,8 @@ class StackTypeSet : public TypeSet
|
||||||
*/
|
*/
|
||||||
static StackTypeSet *make(JSContext *cx, const char *name);
|
static StackTypeSet *make(JSContext *cx, const char *name);
|
||||||
|
|
||||||
/* Constraints for type inference. */
|
/* Propagate any types from this set into target. */
|
||||||
|
void addSubset(JSContext *cx, StackTypeSet *target);
|
||||||
void addSubset(JSContext *cx, TypeSet *target);
|
|
||||||
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
StackTypeSet *target, jsid id);
|
|
||||||
void addSetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
StackTypeSet *target, jsid id);
|
|
||||||
void addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
StackTypeSet *objectTypes, StackTypeSet *valueTypes);
|
|
||||||
void addCall(JSContext *cx, TypeCallsite *site);
|
|
||||||
void addArith(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
TypeSet *target, TypeSet *other = NULL);
|
|
||||||
void addTransformThis(JSContext *cx, JSScript *script, TypeSet *target);
|
|
||||||
void addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
Type type, StackTypeSet *types = NULL);
|
|
||||||
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constraints for JIT compilation.
|
* Constraints for JIT compilation.
|
||||||
|
@ -679,16 +665,8 @@ class HeapTypeSet : public TypeSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* Constraints for type inference. */
|
/* Propagate any types from this set into target. */
|
||||||
|
void addSubset(JSContext *cx, HeapTypeSet *target);
|
||||||
void addSubset(JSContext *cx, TypeSet *target);
|
|
||||||
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|
||||||
StackTypeSet *target, jsid id);
|
|
||||||
void addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid id);
|
|
||||||
void addFilterPrimitives(JSContext *cx, TypeSet *target);
|
|
||||||
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
|
|
||||||
|
|
||||||
/* Constraints for JIT compilation. */
|
|
||||||
|
|
||||||
/* Completely freeze the contents of this type set. */
|
/* Completely freeze the contents of this type set. */
|
||||||
void addFreeze(JSContext *cx);
|
void addFreeze(JSContext *cx);
|
||||||
|
@ -1152,7 +1130,7 @@ struct TypeObject : gc::Cell
|
||||||
void clearAddendum(ExclusiveContext *cx);
|
void clearAddendum(ExclusiveContext *cx);
|
||||||
void clearNewScriptAddendum(ExclusiveContext *cx);
|
void clearNewScriptAddendum(ExclusiveContext *cx);
|
||||||
void clearBinaryDataAddendum(ExclusiveContext *cx);
|
void clearBinaryDataAddendum(ExclusiveContext *cx);
|
||||||
void getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force = false);
|
void getFromPrototypes(JSContext *cx, jsid id, HeapTypeSet *types, bool force = false);
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
|
@ -1500,10 +1478,6 @@ struct TypeCompartment
|
||||||
void addPendingRecompile(JSContext *cx, const RecompileInfo &info);
|
void addPendingRecompile(JSContext *cx, const RecompileInfo &info);
|
||||||
void addPendingRecompile(JSContext *cx, JSScript *script);
|
void addPendingRecompile(JSContext *cx, JSScript *script);
|
||||||
|
|
||||||
/* Monitor future effects on a bytecode. */
|
|
||||||
void monitorBytecode(JSContext *cx, JSScript *script, uint32_t offset,
|
|
||||||
bool returnOnly = false);
|
|
||||||
|
|
||||||
/* Mark any type set containing obj as having a generic object type. */
|
/* Mark any type set containing obj as having a generic object type. */
|
||||||
void markSetsUnknown(JSContext *cx, TypeObject *obj);
|
void markSetsUnknown(JSContext *cx, TypeObject *obj);
|
||||||
|
|
||||||
|
|
|
@ -1682,18 +1682,6 @@ JSScript::ensureRanAnalysis(JSContext *cx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
|
||||||
JSScript::ensureRanInference(JSContext *cx)
|
|
||||||
{
|
|
||||||
if (!ensureRanAnalysis(cx))
|
|
||||||
return false;
|
|
||||||
if (!analysis()->ranInference()) {
|
|
||||||
js::types::AutoEnterAnalysis enter(cx);
|
|
||||||
analysis()->analyzeTypes(cx);
|
|
||||||
}
|
|
||||||
return !analysis()->OOM() && !cx->zone()->types.pendingNukeTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
JSScript::hasAnalysis()
|
JSScript::hasAnalysis()
|
||||||
{
|
{
|
||||||
|
@ -1723,14 +1711,6 @@ JSScript::clearPropertyReadTypes()
|
||||||
types->propertyReadTypes = NULL;
|
types->propertyReadTypes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
|
||||||
js::analyze::ScriptAnalysis::addPushedType(JSContext *cx, uint32_t offset, uint32_t which,
|
|
||||||
js::types::Type type)
|
|
||||||
{
|
|
||||||
js::types::TypeSet *pushed = pushedTypes(offset, which);
|
|
||||||
pushed->addType(cx, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|
|
@ -2834,11 +2834,6 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script->hasAnalysis() && script->analysis()->ranInference()) {
|
|
||||||
types::AutoEnterAnalysis enter(cx);
|
|
||||||
types::TypeScript::MonitorUnknown(cx, script, script->argumentsBytecode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче