Record ToBoolean's type information in Hydrogen's HBranch instruction, so we can use it in LCodeGen::DoBranch later.
Review URL: http://codereview.chromium.org/7491043 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8736 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
561d0cf228
commit
8ebf3993d6
@ -933,6 +933,8 @@ class ToBooleanStub: public CodeStub {
|
||||
EnumSet<Type, byte> set_;
|
||||
};
|
||||
|
||||
static Types no_types() { return Types(); }
|
||||
|
||||
explicit ToBooleanStub(Register tos, Types types = Types())
|
||||
: tos_(tos), types_(types) { }
|
||||
|
||||
|
@ -933,8 +933,12 @@ class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
|
||||
|
||||
class HBranch: public HUnaryControlInstruction {
|
||||
public:
|
||||
HBranch(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
|
||||
: HUnaryControlInstruction(value, true_target, false_target) {
|
||||
HBranch(HValue* value,
|
||||
HBasicBlock* true_target,
|
||||
HBasicBlock* false_target,
|
||||
ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
|
||||
: HUnaryControlInstruction(value, true_target, false_target),
|
||||
expected_input_types_(expected_input_types) {
|
||||
ASSERT(true_target != NULL && false_target != NULL);
|
||||
}
|
||||
explicit HBranch(HValue* value)
|
||||
@ -945,7 +949,14 @@ class HBranch: public HUnaryControlInstruction {
|
||||
return Representation::None();
|
||||
}
|
||||
|
||||
ToBooleanStub::Types expected_input_types() const {
|
||||
return expected_input_types_;
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(Branch)
|
||||
|
||||
private:
|
||||
ToBooleanStub::Types expected_input_types_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -2158,7 +2158,9 @@ void TestContext::BuildBranch(HValue* value) {
|
||||
}
|
||||
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
|
||||
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
|
||||
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false);
|
||||
unsigned test_id = condition()->test_id();
|
||||
ToBooleanStub::Types expected(builder->oracle()->ToBooleanTypes(test_id));
|
||||
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
|
||||
builder->current_block()->Finish(test);
|
||||
|
||||
empty_true->Goto(if_true());
|
||||
@ -5504,9 +5506,11 @@ void HGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
|
||||
// We need an extra block to maintain edge-split form.
|
||||
HBasicBlock* empty_block = graph()->CreateBasicBlock();
|
||||
HBasicBlock* eval_right = graph()->CreateBasicBlock();
|
||||
unsigned test_id = expr->left()->test_id();
|
||||
ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
|
||||
HBranch* test = is_logical_and
|
||||
? new(zone()) HBranch(Top(), eval_right, empty_block)
|
||||
: new(zone()) HBranch(Top(), empty_block, eval_right);
|
||||
? new(zone()) HBranch(Top(), eval_right, empty_block, expected)
|
||||
: new(zone()) HBranch(Top(), empty_block, eval_right, expected);
|
||||
current_block()->Finish(test);
|
||||
|
||||
set_current_block(eval_right);
|
||||
|
@ -719,6 +719,8 @@ class HGraphBuilder: public AstVisitor {
|
||||
HBasicBlock* second,
|
||||
int join_id);
|
||||
|
||||
TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
|
||||
|
||||
private:
|
||||
// Type of a member function that generates inline code for a native function.
|
||||
typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call);
|
||||
@ -747,7 +749,6 @@ class HGraphBuilder: public AstVisitor {
|
||||
CompilationInfo* info() const {
|
||||
return function_state()->compilation_info();
|
||||
}
|
||||
TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
|
||||
|
||||
AstContext* call_context() const {
|
||||
return function_state()->call_context();
|
||||
|
@ -572,7 +572,7 @@ void FullCodeGenerator::DoTest(Expression* condition,
|
||||
Label* fall_through) {
|
||||
ToBooleanStub stub(result_register());
|
||||
__ push(result_register());
|
||||
__ CallStub(&stub);
|
||||
__ CallStub(&stub, condition->test_id());
|
||||
__ test(result_register(), Operand(result_register()));
|
||||
// The stub returns nonzero for true.
|
||||
Split(not_zero, if_true, if_false, fall_through);
|
||||
|
@ -439,6 +439,12 @@ void TypeFeedbackOracle::CollectKeyedReceiverTypes(
|
||||
}
|
||||
|
||||
|
||||
byte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) {
|
||||
Handle<Object> object = GetInfo(ast_id);
|
||||
return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
|
||||
}
|
||||
|
||||
|
||||
// Things are a bit tricky here: The iterator for the RelocInfos and the infos
|
||||
// themselves are not GC-safe, so we first get all infos, then we create the
|
||||
// dictionary (possibly triggering GC), and finally we relocate the collected
|
||||
@ -523,6 +529,7 @@ void TypeFeedbackOracle::ProcessTarget(unsigned ast_id, Code* target) {
|
||||
case Code::UNARY_OP_IC:
|
||||
case Code::BINARY_OP_IC:
|
||||
case Code::COMPARE_IC:
|
||||
case Code::TO_BOOLEAN_IC:
|
||||
SetInfo(ast_id, target);
|
||||
break;
|
||||
|
||||
|
@ -238,6 +238,11 @@ class TypeFeedbackOracle BASE_EMBEDDED {
|
||||
|
||||
bool LoadIsBuiltin(Property* expr, Builtins::Name id);
|
||||
|
||||
// TODO(1571) We can't use ToBooleanStub::Types as the return value because
|
||||
// of various cylces in our headers. Death to tons of implementations in
|
||||
// headers!! :-P
|
||||
byte ToBooleanTypes(unsigned ast_id);
|
||||
|
||||
// Get type information for arithmetic operations and compares.
|
||||
TypeInfo UnaryType(UnaryOperation* expr);
|
||||
TypeInfo BinaryType(BinaryOperation* expr);
|
||||
|
Loading…
Reference in New Issue
Block a user