mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 763599 - Inline string[int32] GETELEM. r=dvander
This commit is contained in:
parent
26ac034690
commit
3b751cbef4
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
11
js/src/jit-test/tests/ion/getelem-string.js
Normal file
11
js/src/jit-test/tests/ion/getelem-string.js
Normal 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();
|
Loading…
Reference in New Issue
Block a user