Revert r6194: Clean up code for type feedback a bit.
This causes a big performance regression. I'll investigate. Review URL: http://codereview.chromium.org/6172001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6217 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
12b34fa927
commit
bfecc95694
14
src/ast.cc
14
src/ast.cc
@ -649,11 +649,19 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
}
|
||||
|
||||
|
||||
void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
TypeInfo left = oracle->BinaryType(this, TypeFeedbackOracle::LEFT);
|
||||
TypeInfo right = oracle->BinaryType(this, TypeFeedbackOracle::RIGHT);
|
||||
is_smi_only_ = left.IsSmi() && right.IsSmi();
|
||||
}
|
||||
|
||||
|
||||
void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
TypeInfo info = oracle->CompareType(this);
|
||||
if (info.IsSmi()) {
|
||||
TypeInfo left = oracle->CompareType(this, TypeFeedbackOracle::LEFT);
|
||||
TypeInfo right = oracle->CompareType(this, TypeFeedbackOracle::RIGHT);
|
||||
if (left.IsSmi() && right.IsSmi()) {
|
||||
compare_type_ = SMI_ONLY;
|
||||
} else if (info.IsNonPrimitive()) {
|
||||
} else if (left.IsNonPrimitive() && right.IsNonPrimitive()) {
|
||||
compare_type_ = OBJECT_ONLY;
|
||||
} else {
|
||||
ASSERT(compare_type_ == NONE);
|
||||
|
@ -1392,7 +1392,7 @@ class BinaryOperation: public Expression {
|
||||
Expression* left,
|
||||
Expression* right,
|
||||
int pos)
|
||||
: op_(op), left_(left), right_(right), pos_(pos) {
|
||||
: op_(op), left_(left), right_(right), pos_(pos), is_smi_only_(false) {
|
||||
ASSERT(Token::IsBinaryOp(op));
|
||||
right_id_ = (op == Token::AND || op == Token::OR)
|
||||
? static_cast<int>(GetNextId())
|
||||
@ -1413,6 +1413,10 @@ class BinaryOperation: public Expression {
|
||||
Expression* right() const { return right_; }
|
||||
int position() const { return pos_; }
|
||||
|
||||
// Type feedback information.
|
||||
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
|
||||
bool IsSmiOnly() const { return is_smi_only_; }
|
||||
|
||||
// Bailout support.
|
||||
int RightId() const { return right_id_; }
|
||||
|
||||
@ -1421,6 +1425,7 @@ class BinaryOperation: public Expression {
|
||||
Expression* left_;
|
||||
Expression* right_;
|
||||
int pos_;
|
||||
bool is_smi_only_;
|
||||
// The short-circuit logical operations have an AST ID for their
|
||||
// right-hand subexpression.
|
||||
int right_id_;
|
||||
|
@ -3366,6 +3366,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
|
||||
// We have a second position recorded in the FullCodeGenerator to have
|
||||
// type feedback for the binary operation.
|
||||
BinaryOperation* operation = expr->binary_operation();
|
||||
operation->RecordTypeFeedback(oracle());
|
||||
|
||||
if (var != NULL) {
|
||||
if (!var->is_global() && !var->IsStackAllocated()) {
|
||||
@ -4730,7 +4731,7 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
TypeInfo info = oracle()->BinaryType(expr);
|
||||
TypeInfo info = oracle()->BinaryType(expr, TypeFeedbackOracle::RESULT);
|
||||
// If we hit an uninitialized binary op stub we will get type info
|
||||
// for a smi operation. If one of the operands is a constant string
|
||||
// do not generate code assuming it is a smi operation.
|
||||
@ -4875,7 +4876,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
||||
HValue* left = Pop();
|
||||
Token::Value op = expr->op();
|
||||
|
||||
TypeInfo info = oracle()->CompareType(expr);
|
||||
TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT);
|
||||
HInstruction* instr = NULL;
|
||||
if (op == Token::INSTANCEOF) {
|
||||
// Check to see if the rhs of the instanceof is a global function not
|
||||
|
@ -132,7 +132,7 @@ bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
|
||||
}
|
||||
|
||||
|
||||
TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
|
||||
TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr, Side side) {
|
||||
Handle<Object> object = GetElement(map_, expr->position());
|
||||
TypeInfo unknown = TypeInfo::Unknown();
|
||||
if (!object->IsCode()) return unknown;
|
||||
@ -159,12 +159,27 @@ TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
|
||||
}
|
||||
|
||||
|
||||
TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
|
||||
TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) {
|
||||
Handle<Object> object = GetElement(map_, expr->position());
|
||||
TypeInfo unknown = TypeInfo::Unknown();
|
||||
if (!object->IsCode()) return unknown;
|
||||
Handle<Code> code = Handle<Code>::cast(object);
|
||||
if (code->is_type_recording_binary_op_stub()) {
|
||||
if (code->is_binary_op_stub()) {
|
||||
BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
|
||||
code->binary_op_type());
|
||||
switch (type) {
|
||||
case BinaryOpIC::UNINIT_OR_SMI:
|
||||
return TypeInfo::Smi();
|
||||
case BinaryOpIC::DEFAULT:
|
||||
return (expr->op() == Token::DIV || expr->op() == Token::MUL)
|
||||
? TypeInfo::Double()
|
||||
: TypeInfo::Integer32();
|
||||
case BinaryOpIC::HEAP_NUMBERS:
|
||||
return TypeInfo::Double();
|
||||
default:
|
||||
return unknown;
|
||||
}
|
||||
} else if (code->is_type_recording_binary_op_stub()) {
|
||||
TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
|
||||
code->type_recording_binary_op_type());
|
||||
TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>(
|
||||
@ -276,7 +291,8 @@ void TypeFeedbackOracle::PopulateMap(Handle<Code> code) {
|
||||
int position = source_positions[i];
|
||||
InlineCacheState state = target->ic_state();
|
||||
Code::Kind kind = target->kind();
|
||||
if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
|
||||
if (kind == Code::BINARY_OP_IC ||
|
||||
kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
|
||||
kind == Code::COMPARE_IC) {
|
||||
// TODO(kasperl): Avoid having multiple ICs with the same
|
||||
// position by making sure that we have position information
|
||||
@ -316,18 +332,20 @@ void TypeFeedbackOracle::CollectPositions(Code* code,
|
||||
if (target->is_inline_cache_stub()) {
|
||||
InlineCacheState state = target->ic_state();
|
||||
Code::Kind kind = target->kind();
|
||||
if (kind == Code::TYPE_RECORDING_BINARY_OP_IC &&
|
||||
target->type_recording_binary_op_type() == TRBinaryOpIC::GENERIC) {
|
||||
continue;
|
||||
} else if (kind == Code::COMPARE_IC &&
|
||||
target->compare_state() == CompareIC::GENERIC) {
|
||||
continue;
|
||||
} else if (kind == Code::CALL_IC && state == MONOMORPHIC &&
|
||||
target->check_type() != RECEIVER_MAP_CHECK) {
|
||||
continue;
|
||||
} else if (state != MONOMORPHIC && state != MEGAMORPHIC) {
|
||||
if (kind == Code::BINARY_OP_IC) {
|
||||
if (target->binary_op_type() == BinaryOpIC::GENERIC) continue;
|
||||
} else if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
|
||||
if (target->type_recording_binary_op_type() ==
|
||||
TRBinaryOpIC::GENERIC) {
|
||||
continue;
|
||||
}
|
||||
} else if (kind == Code::COMPARE_IC) {
|
||||
if (target->compare_state() == CompareIC::GENERIC) continue;
|
||||
} else {
|
||||
if (kind == Code::CALL_IC && state == MONOMORPHIC &&
|
||||
target->check_type() != RECEIVER_MAP_CHECK) continue;
|
||||
if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
|
||||
}
|
||||
code_positions->Add(
|
||||
static_cast<int>(info->pc() - code->instruction_start()));
|
||||
source_positions->Add(position);
|
||||
|
@ -230,6 +230,12 @@ class CaseClause;
|
||||
|
||||
class TypeFeedbackOracle BASE_EMBEDDED {
|
||||
public:
|
||||
enum Side {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
RESULT
|
||||
};
|
||||
|
||||
explicit TypeFeedbackOracle(Handle<Code> code);
|
||||
|
||||
bool LoadIsMonomorphic(Property* expr);
|
||||
@ -247,8 +253,8 @@ class TypeFeedbackOracle BASE_EMBEDDED {
|
||||
bool LoadIsBuiltin(Property* expr, Builtins::Name id);
|
||||
|
||||
// Get type information for arithmetic operations and compares.
|
||||
TypeInfo BinaryType(BinaryOperation* expr);
|
||||
TypeInfo CompareType(CompareOperation* expr);
|
||||
TypeInfo BinaryType(BinaryOperation* expr, Side side);
|
||||
TypeInfo CompareType(CompareOperation* expr, Side side);
|
||||
TypeInfo SwitchType(CaseClause* clause);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user