Bug 763599 - Inline string[int32] GETELEM. r=dvander

This commit is contained in:
Jan de Mooij 2012-06-13 10:56:31 +02:00
parent 26ac034690
commit 3b751cbef4
7 changed files with 77 additions and 6 deletions

View File

@ -3934,6 +3934,9 @@ IonBuilder::jsop_getelem()
if (oracle->elementReadIsTypedArray(script, pc, &arrayType))
return jsop_getelem_typed(arrayType);
if (oracle->elementReadIsString(script, pc))
return jsop_getelem_string();
MDefinition *rhs = current->pop();
MDefinition *lhs = current->pop();
@ -4124,6 +4127,31 @@ IonBuilder::jsop_getelem_typed(int arrayType)
}
}
bool
IonBuilder::jsop_getelem_string()
{
MDefinition *id = current->pop();
MDefinition *str = current->pop();
MInstruction *idInt32 = MToInt32::New(id);
current->add(idInt32);
id = idInt32;
MStringLength *length = MStringLength::New(str);
current->add(length);
MBoundsCheck *boundsCheck = MBoundsCheck::New(id, length);
current->add(boundsCheck);
MCharCodeAt *charCode = MCharCodeAt::New(str, id);
current->add(charCode);
MFromCharCode *result = MFromCharCode::New(charCode);
current->add(result);
current->push(result);
return true;
}
bool
IonBuilder::jsop_setelem()
{

View File

@ -329,6 +329,7 @@ class IonBuilder : public MIRGenerator
bool jsop_getelem();
bool jsop_getelem_dense();
bool jsop_getelem_typed(int arrayType);
bool jsop_getelem_string();
bool jsop_setelem();
bool jsop_setelem_dense();
bool jsop_setelem_typed(int arrayType);

View File

@ -248,12 +248,12 @@ IonBuilder::inlineNativeCall(JSFunction *target, uint32 argc, bool constructing)
MBoundsCheck *boundsCheck = MBoundsCheck::New(indexOrCode, length);
current->add(length);
current->add(boundsCheck);
ins = new MCharCodeAt(str, indexOrCode);
ins = MCharCodeAt::New(str, indexOrCode);
current->add(ins);
indexOrCode = ins;
}
if (native == js::str_fromCharCode || native == js_str_charAt) {
ins = new MFromCharCode(indexOrCode);
ins = MFromCharCode::New(indexOrCode);
current->add(ins);
}
current->push(ins);

View File

@ -2302,7 +2302,6 @@ class MCharCodeAt
: public MBinaryInstruction,
public MixPolicy<StringPolicy, IntPolicy<1> >
{
public:
MCharCodeAt(MDefinition *str, MDefinition *index)
: MBinaryInstruction(str, index)
{
@ -2310,14 +2309,20 @@ class MCharCodeAt
setResultType(MIRType_Int32);
}
public:
INSTRUCTION_HEADER(CharCodeAt);
static MCharCodeAt *New(MDefinition *str, MDefinition *index) {
return new MCharCodeAt(str, index);
}
TypePolicy *typePolicy() {
return this;
}
virtual AliasSet getAliasSet() const {
return AliasSet::Load(AliasSet::ObjectFields);
// Strings are immutable, so there is no implicit dependency.
return AliasSet::None();
}
};
@ -2325,7 +2330,6 @@ class MFromCharCode
: public MUnaryInstruction,
public IntPolicy<0>
{
public:
MFromCharCode(MDefinition *code)
: MUnaryInstruction(code)
{
@ -2333,8 +2337,13 @@ class MFromCharCode
setResultType(MIRType_String);
}
public:
INSTRUCTION_HEADER(FromCharCode);
static MFromCharCode *New(MDefinition *code) {
return new MFromCharCode(code);
}
virtual AliasSet getAliasSet() const {
return AliasSet::None();
}
@ -4141,7 +4150,9 @@ class MStringLength
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const {
return AliasSet::Load(AliasSet::ObjectFields);
// The string |length| property is immutable, so there is no
// implicit dependency.
return AliasSet::None();
}
};

View File

@ -310,6 +310,22 @@ TypeInferenceOracle::elementReadIsTypedArray(JSScript *script, jsbytecode *pc, i
return true;
}
bool
TypeInferenceOracle::elementReadIsString(JSScript *script, jsbytecode *pc)
{
// Check for string[int32].
types::TypeSet *value = script->analysis()->poppedTypes(pc, 1);
types::TypeSet *id = script->analysis()->poppedTypes(pc, 0);
if (value->getKnownTypeTag(cx) != JSVAL_TYPE_STRING)
return false;
if (id->getKnownTypeTag(cx) != JSVAL_TYPE_INT32)
return false;
return true;
}
bool
TypeInferenceOracle::elementReadIsPacked(JSScript *script, jsbytecode *pc)
{

View File

@ -126,6 +126,9 @@ class TypeOracle
virtual bool elementReadIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType) {
return false;
}
virtual bool elementReadIsString(JSScript *script, jsbytecode *pc) {
return false;
}
virtual bool elementReadIsPacked(JSScript *script, jsbytecode *pc) {
return false;
}
@ -241,6 +244,7 @@ class TypeInferenceOracle : public TypeOracle
types::TypeSet *getCallReturn(JSScript *caller, jsbytecode *pc);
bool elementReadIsDenseArray(JSScript *script, jsbytecode *pc);
bool elementReadIsTypedArray(JSScript *script, jsbytecode *pc, int *atype);
bool elementReadIsString(JSScript *script, jsbytecode *pc);
bool elementReadIsPacked(JSScript *script, jsbytecode *pc);
void elementReadGeneric(JSScript *script, jsbytecode *pc, bool *cacheable, bool *monitorResult);
bool elementWriteIsDenseArray(JSScript *script, jsbytecode *pc);

View File

@ -0,0 +1,11 @@
function test1() {
function getchar(s, i) {
return s[i];
}
for (var i=0; i<70; i++) {
assertEq(getchar("foo", 0), "f");
assertEq(getchar("bar", 2), "r");
}
assertEq(getchar("foo", 3), undefined);
}
test1();