Crankshaft support for IN.
In JavaScriptFrame::Print avoid printing optimized frame as if it is unoptimized. Review URL: http://codereview.chromium.org/6894043 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7682 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
08e7b94924
commit
b62bdda7d1
@ -2142,4 +2142,12 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIn(HIn* instr) {
|
||||
LOperand* key = UseRegisterAtStart(instr->key());
|
||||
LOperand* object = UseRegisterAtStart(instr->object());
|
||||
LIn* result = new LIn(key, object);
|
||||
return MarkAsCall(DefineFixed(result, r0), instr);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -102,6 +102,7 @@ class LCodeGen;
|
||||
V(HasCachedArrayIndexAndBranch) \
|
||||
V(HasInstanceType) \
|
||||
V(HasInstanceTypeAndBranch) \
|
||||
V(In) \
|
||||
V(InstanceOf) \
|
||||
V(InstanceOfAndBranch) \
|
||||
V(InstanceOfKnownGlobal) \
|
||||
@ -1992,6 +1993,20 @@ class LStackCheck: public LTemplateInstruction<0, 0, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIn: public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LIn(LOperand* key, LOperand* object) {
|
||||
inputs_[0] = key;
|
||||
inputs_[1] = object;
|
||||
}
|
||||
|
||||
LOperand* key() { return inputs_[0]; }
|
||||
LOperand* object() { return inputs_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(In, "in")
|
||||
};
|
||||
|
||||
|
||||
class LChunkBuilder;
|
||||
class LChunk: public ZoneObject {
|
||||
public:
|
||||
|
@ -4257,6 +4257,22 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIn(LIn* instr) {
|
||||
Register obj = ToRegister(instr->object());
|
||||
Register key = ToRegister(instr->key());
|
||||
__ Push(key, obj);
|
||||
ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
|
||||
LPointerMap* pointers = instr->pointer_map();
|
||||
LEnvironment* env = instr->deoptimization_environment();
|
||||
RecordPosition(pointers->position());
|
||||
RegisterEnvironmentForDeoptimization(env);
|
||||
SafepointGenerator safepoint_generator(this,
|
||||
pointers,
|
||||
env->deoptimization_index());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_JS, &safepoint_generator);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
||||
// Perform stack overflow check.
|
||||
Label ok;
|
||||
@ -4286,6 +4302,8 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#undef __
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -938,6 +938,10 @@ void JavaScriptFrame::Print(StringStream* accumulator,
|
||||
accumulator->Add("\n");
|
||||
return;
|
||||
}
|
||||
if (is_optimized()) {
|
||||
accumulator->Add(" {\n// optimized frame\n}\n");
|
||||
return;
|
||||
}
|
||||
accumulator->Add(" {\n");
|
||||
|
||||
// Compute the number of locals and expression stack elements.
|
||||
|
@ -1611,6 +1611,13 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) {
|
||||
}
|
||||
|
||||
|
||||
void HIn::PrintDataTo(StringStream* stream) {
|
||||
key()->PrintNameTo(stream);
|
||||
stream->Add(" ");
|
||||
object()->PrintNameTo(stream);
|
||||
}
|
||||
|
||||
|
||||
// Node-specific verification code is only included in debug mode.
|
||||
#ifdef DEBUG
|
||||
|
||||
|
@ -104,6 +104,7 @@ class LChunkBuilder;
|
||||
V(Goto) \
|
||||
V(HasInstanceType) \
|
||||
V(HasCachedArrayIndex) \
|
||||
V(In) \
|
||||
V(InstanceOf) \
|
||||
V(InstanceOfKnownGlobal) \
|
||||
V(InvokeFunction) \
|
||||
@ -3780,6 +3781,32 @@ class HDeleteProperty: public HBinaryOperation {
|
||||
HValue* key() { return right(); }
|
||||
};
|
||||
|
||||
|
||||
class HIn: public HTemplateInstruction<2> {
|
||||
public:
|
||||
HIn(HValue* key, HValue* object) {
|
||||
SetOperandAt(0, key);
|
||||
SetOperandAt(1, object);
|
||||
set_representation(Representation::Tagged());
|
||||
SetAllSideEffects();
|
||||
}
|
||||
|
||||
HValue* key() { return OperandAt(0); }
|
||||
HValue* object() { return OperandAt(1); }
|
||||
|
||||
virtual Representation RequiredInputRepresentation(int index) const {
|
||||
return Representation::Tagged();
|
||||
}
|
||||
|
||||
virtual HType CalculateInferredType() {
|
||||
return HType::Boolean();
|
||||
}
|
||||
|
||||
virtual void PrintDataTo(StringStream* stream);
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(In)
|
||||
};
|
||||
|
||||
#undef DECLARE_INSTRUCTION
|
||||
#undef DECLARE_CONCRETE_INSTRUCTION
|
||||
|
||||
|
@ -5105,7 +5105,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
||||
instr = new(zone()) HInstanceOfKnownGlobal(left, target);
|
||||
}
|
||||
} else if (op == Token::IN) {
|
||||
return Bailout("Unsupported comparison: in");
|
||||
instr = new(zone()) HIn(left, right);
|
||||
} else if (type_info.IsNonPrimitive()) {
|
||||
switch (op) {
|
||||
case Token::EQ:
|
||||
|
@ -4218,6 +4218,35 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIn(LIn* instr) {
|
||||
LOperand* obj = instr->object();
|
||||
LOperand* key = instr->key();
|
||||
if (key->IsConstantOperand()) {
|
||||
__ push(ToImmediate(key));
|
||||
} else {
|
||||
__ push(ToOperand(key));
|
||||
}
|
||||
if (obj->IsConstantOperand()) {
|
||||
__ push(ToImmediate(obj));
|
||||
} else {
|
||||
__ push(ToOperand(obj));
|
||||
}
|
||||
ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
|
||||
LPointerMap* pointers = instr->pointer_map();
|
||||
LEnvironment* env = instr->deoptimization_environment();
|
||||
RecordPosition(pointers->position());
|
||||
RegisterEnvironmentForDeoptimization(env);
|
||||
// Create safepoint generator that will also ensure enough space in the
|
||||
// reloc info for patching in deoptimization (since this is invoking a
|
||||
// builtin)
|
||||
SafepointGenerator safepoint_generator(this,
|
||||
pointers,
|
||||
env->deoptimization_index());
|
||||
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
|
||||
}
|
||||
|
||||
|
||||
#undef __
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -2205,6 +2205,14 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIn(HIn* instr) {
|
||||
LOperand* key = UseOrConstantAtStart(instr->key());
|
||||
LOperand* object = UseOrConstantAtStart(instr->object());
|
||||
LIn* result = new LIn(key, object);
|
||||
return MarkAsCall(DefineFixed(result, eax), instr);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_TARGET_ARCH_IA32
|
||||
|
@ -103,6 +103,7 @@ class LCodeGen;
|
||||
V(HasCachedArrayIndexAndBranch) \
|
||||
V(HasInstanceType) \
|
||||
V(HasInstanceTypeAndBranch) \
|
||||
V(In) \
|
||||
V(InstanceOf) \
|
||||
V(InstanceOfAndBranch) \
|
||||
V(InstanceOfKnownGlobal) \
|
||||
@ -2045,6 +2046,20 @@ class LStackCheck: public LTemplateInstruction<0, 0, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIn: public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LIn(LOperand* key, LOperand* object) {
|
||||
inputs_[0] = key;
|
||||
inputs_[1] = object;
|
||||
}
|
||||
|
||||
LOperand* key() { return inputs_[0]; }
|
||||
LOperand* object() { return inputs_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(In, "in")
|
||||
};
|
||||
|
||||
|
||||
class LChunkBuilder;
|
||||
class LChunk: public ZoneObject {
|
||||
public:
|
||||
|
@ -3998,6 +3998,26 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIn(LIn* instr) {
|
||||
LOperand* obj = instr->object();
|
||||
LOperand* key = instr->key();
|
||||
EmitPushTaggedOperand(key);
|
||||
EmitPushTaggedOperand(obj);
|
||||
ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
|
||||
LPointerMap* pointers = instr->pointer_map();
|
||||
LEnvironment* env = instr->deoptimization_environment();
|
||||
RecordPosition(pointers->position());
|
||||
RegisterEnvironmentForDeoptimization(env);
|
||||
// Create safepoint generator that will also ensure enough space in the
|
||||
// reloc info for patching in deoptimization (since this is invoking a
|
||||
// builtin)
|
||||
SafepointGenerator safepoint_generator(this,
|
||||
pointers,
|
||||
env->deoptimization_index());
|
||||
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
||||
// Perform stack overflow check.
|
||||
NearLabel done;
|
||||
|
@ -2136,6 +2136,15 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIn(HIn* instr) {
|
||||
LOperand* key = UseOrConstantAtStart(instr->key());
|
||||
LOperand* object = UseOrConstantAtStart(instr->object());
|
||||
LIn* result = new LIn(key, object);
|
||||
return MarkAsCall(DefineFixed(result, rax), instr);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
|
@ -102,6 +102,7 @@ class LCodeGen;
|
||||
V(HasCachedArrayIndexAndBranch) \
|
||||
V(HasInstanceType) \
|
||||
V(HasInstanceTypeAndBranch) \
|
||||
V(In) \
|
||||
V(InstanceOf) \
|
||||
V(InstanceOfAndBranch) \
|
||||
V(InstanceOfKnownGlobal) \
|
||||
@ -830,6 +831,20 @@ class LCmpTAndBranch: public LControlInstruction<2, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIn: public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LIn(LOperand* key, LOperand* object) {
|
||||
inputs_[0] = key;
|
||||
inputs_[1] = object;
|
||||
}
|
||||
|
||||
LOperand* key() { return inputs_[0]; }
|
||||
LOperand* object() { return inputs_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(In, "in")
|
||||
};
|
||||
|
||||
|
||||
class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LInstanceOf(LOperand* left, LOperand* right) {
|
||||
|
Loading…
Reference in New Issue
Block a user