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
|
} } // namespace v8::internal
|
||||||
|
@ -102,6 +102,7 @@ class LCodeGen;
|
|||||||
V(HasCachedArrayIndexAndBranch) \
|
V(HasCachedArrayIndexAndBranch) \
|
||||||
V(HasInstanceType) \
|
V(HasInstanceType) \
|
||||||
V(HasInstanceTypeAndBranch) \
|
V(HasInstanceTypeAndBranch) \
|
||||||
|
V(In) \
|
||||||
V(InstanceOf) \
|
V(InstanceOf) \
|
||||||
V(InstanceOfAndBranch) \
|
V(InstanceOfAndBranch) \
|
||||||
V(InstanceOfKnownGlobal) \
|
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 LChunkBuilder;
|
||||||
class LChunk: public ZoneObject {
|
class LChunk: public ZoneObject {
|
||||||
public:
|
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) {
|
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
||||||
// Perform stack overflow check.
|
// Perform stack overflow check.
|
||||||
Label ok;
|
Label ok;
|
||||||
@ -4286,6 +4302,8 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef __
|
#undef __
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
@ -938,6 +938,10 @@ void JavaScriptFrame::Print(StringStream* accumulator,
|
|||||||
accumulator->Add("\n");
|
accumulator->Add("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (is_optimized()) {
|
||||||
|
accumulator->Add(" {\n// optimized frame\n}\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
accumulator->Add(" {\n");
|
accumulator->Add(" {\n");
|
||||||
|
|
||||||
// Compute the number of locals and expression stack elements.
|
// 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.
|
// Node-specific verification code is only included in debug mode.
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
@ -104,6 +104,7 @@ class LChunkBuilder;
|
|||||||
V(Goto) \
|
V(Goto) \
|
||||||
V(HasInstanceType) \
|
V(HasInstanceType) \
|
||||||
V(HasCachedArrayIndex) \
|
V(HasCachedArrayIndex) \
|
||||||
|
V(In) \
|
||||||
V(InstanceOf) \
|
V(InstanceOf) \
|
||||||
V(InstanceOfKnownGlobal) \
|
V(InstanceOfKnownGlobal) \
|
||||||
V(InvokeFunction) \
|
V(InvokeFunction) \
|
||||||
@ -3780,6 +3781,32 @@ class HDeleteProperty: public HBinaryOperation {
|
|||||||
HValue* key() { return right(); }
|
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_INSTRUCTION
|
||||||
#undef DECLARE_CONCRETE_INSTRUCTION
|
#undef DECLARE_CONCRETE_INSTRUCTION
|
||||||
|
|
||||||
|
@ -5105,7 +5105,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
instr = new(zone()) HInstanceOfKnownGlobal(left, target);
|
instr = new(zone()) HInstanceOfKnownGlobal(left, target);
|
||||||
}
|
}
|
||||||
} else if (op == Token::IN) {
|
} else if (op == Token::IN) {
|
||||||
return Bailout("Unsupported comparison: in");
|
instr = new(zone()) HIn(left, right);
|
||||||
} else if (type_info.IsNonPrimitive()) {
|
} else if (type_info.IsNonPrimitive()) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Token::EQ:
|
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 __
|
#undef __
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // 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
|
} } // namespace v8::internal
|
||||||
|
|
||||||
#endif // V8_TARGET_ARCH_IA32
|
#endif // V8_TARGET_ARCH_IA32
|
||||||
|
@ -103,6 +103,7 @@ class LCodeGen;
|
|||||||
V(HasCachedArrayIndexAndBranch) \
|
V(HasCachedArrayIndexAndBranch) \
|
||||||
V(HasInstanceType) \
|
V(HasInstanceType) \
|
||||||
V(HasInstanceTypeAndBranch) \
|
V(HasInstanceTypeAndBranch) \
|
||||||
|
V(In) \
|
||||||
V(InstanceOf) \
|
V(InstanceOf) \
|
||||||
V(InstanceOfAndBranch) \
|
V(InstanceOfAndBranch) \
|
||||||
V(InstanceOfKnownGlobal) \
|
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 LChunkBuilder;
|
||||||
class LChunk: public ZoneObject {
|
class LChunk: public ZoneObject {
|
||||||
public:
|
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) {
|
void LCodeGen::DoStackCheck(LStackCheck* instr) {
|
||||||
// Perform stack overflow check.
|
// Perform stack overflow check.
|
||||||
NearLabel done;
|
NearLabel done;
|
||||||
|
@ -2136,6 +2136,15 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
|||||||
return NULL;
|
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
|
} } // namespace v8::internal
|
||||||
|
|
||||||
#endif // V8_TARGET_ARCH_X64
|
#endif // V8_TARGET_ARCH_X64
|
||||||
|
@ -102,6 +102,7 @@ class LCodeGen;
|
|||||||
V(HasCachedArrayIndexAndBranch) \
|
V(HasCachedArrayIndexAndBranch) \
|
||||||
V(HasInstanceType) \
|
V(HasInstanceType) \
|
||||||
V(HasInstanceTypeAndBranch) \
|
V(HasInstanceTypeAndBranch) \
|
||||||
|
V(In) \
|
||||||
V(InstanceOf) \
|
V(InstanceOf) \
|
||||||
V(InstanceOfAndBranch) \
|
V(InstanceOfAndBranch) \
|
||||||
V(InstanceOfKnownGlobal) \
|
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> {
|
class LInstanceOf: public LTemplateInstruction<1, 2, 0> {
|
||||||
public:
|
public:
|
||||||
LInstanceOf(LOperand* left, LOperand* right) {
|
LInstanceOf(LOperand* left, LOperand* right) {
|
||||||
|
Loading…
Reference in New Issue
Block a user