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:
vegorov@chromium.org 2011-04-26 15:22:44 +00:00
parent 08e7b94924
commit b62bdda7d1
13 changed files with 176 additions and 1 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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) {