}
-HInstruction* HGraphBuilder::BuildIncrement(HValue* value, bool increment) {
+HInstruction* HGraphBuilder::BuildIncrement(HValue* value,
+ bool increment,
+ CountOperation* expr) {
HConstant* delta = increment
? graph_->GetConstant1()
: graph_->GetConstantMinus1();
HInstruction* instr = new(zone()) HAdd(value, delta);
- AssumeRepresentation(instr, Representation::Integer32());
+ Representation rep = ToRepresentation(oracle()->IncrementType(expr));
+ if (rep.IsTagged()) {
+ rep = Representation::Integer32();
+ }
+ AssumeRepresentation(instr, rep);
return instr;
}
// element for postfix operations in a non-effect context.
bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
HValue* before = has_extra ? Top() : Pop();
- HInstruction* after = BuildIncrement(before, inc);
+ HInstruction* after = BuildIncrement(before, inc, expr);
AddInstruction(after);
Push(after);
HValue* before = Pop();
// There is no deoptimization to after the increment, so we don't need
// to simulate the expression stack after this instruction.
- HInstruction* after = BuildIncrement(before, inc);
+ HInstruction* after = BuildIncrement(before, inc, expr);
AddInstruction(after);
HInstruction* store = BuildStoreNamed(obj, after, prop);
HValue* before = Pop();
// There is no deoptimization to after the increment, so we don't need
// to simulate the expression stack after this instruction.
- HInstruction* after = BuildIncrement(before, inc);
+ HInstruction* after = BuildIncrement(before, inc, expr);
AddInstruction(after);
expr->RecordTypeFeedback(oracle());
HInstruction* BuildBinaryOperation(BinaryOperation* expr,
HValue* left,
HValue* right);
- HInstruction* BuildIncrement(HValue* value, bool increment);
+ HInstruction* BuildIncrement(HValue* value,
+ bool increment,
+ CountOperation* expr);
HLoadNamedField* BuildLoadNamedField(HValue* object,
Property* expr,
Handle<Map> type,
}
+TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
+ Handle<Object> object = GetInfo(expr->CountId());
+ TypeInfo unknown = TypeInfo::Unknown();
+ if (!object->IsCode()) return unknown;
+ Handle<Code> code = Handle<Code>::cast(object);
+ if (!code->is_type_recording_binary_op_stub()) return unknown;
+
+ TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
+ code->type_recording_binary_op_type());
+ switch (type) {
+ case TRBinaryOpIC::UNINITIALIZED:
+ case TRBinaryOpIC::SMI:
+ return TypeInfo::Smi();
+ case TRBinaryOpIC::INT32:
+ return TypeInfo::Integer32();
+ case TRBinaryOpIC::HEAP_NUMBER:
+ return TypeInfo::Double();
+ case TRBinaryOpIC::BOTH_STRING:
+ case TRBinaryOpIC::STRING:
+ case TRBinaryOpIC::GENERIC:
+ return unknown;
+ default:
+ return unknown;
+ }
+ UNREACHABLE();
+ return unknown;
+}
+
+
ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
Handle<String> name,
Code::Flags flags) {
class BinaryOperation;
class Call;
class CompareOperation;
+class CountOperation;
class CompilationInfo;
class Property;
class CaseClause;
TypeInfo BinaryType(BinaryOperation* expr);
TypeInfo CompareType(CompareOperation* expr);
TypeInfo SwitchType(CaseClause* clause);
+ TypeInfo IncrementType(CountOperation* expr);
private:
ZoneMapList* CollectReceiverTypes(unsigned ast_id,