Introduce basic type feedback for for-in statements to avoid deopts.
R=fschneider@chromium.org Review URL: https://chromiumcodereview.appspot.com/9571001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10901 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
774e3f4575
commit
ff6ebf7dff
@ -1004,6 +1004,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
// We got a fixed array in register r0. Iterate through that.
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
|
||||
RecordTypeFeedbackCell(stmt->PrepareId(), cell);
|
||||
__ LoadHeapObject(r1, cell);
|
||||
__ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
|
||||
__ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset));
|
||||
|
||||
__ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
|
||||
__ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
|
||||
STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
|
||||
|
@ -3274,6 +3274,10 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
|
||||
return Bailout("ForInStatement optimization is disabled");
|
||||
}
|
||||
|
||||
if (!oracle()->IsForInFastCase(stmt)) {
|
||||
return Bailout("ForInStatement is not fast case");
|
||||
}
|
||||
|
||||
if (!stmt->each()->IsVariableProxy() ||
|
||||
!stmt->each()->AsVariableProxy()->var()->IsStackLocal()) {
|
||||
return Bailout("ForInStatement with non-local each variable");
|
||||
|
@ -1033,6 +1033,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
// We got a fixed array in register eax. Iterate through that.
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
|
||||
RecordTypeFeedbackCell(stmt->PrepareId(), cell);
|
||||
__ LoadHeapObject(ebx, cell);
|
||||
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
|
||||
Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
|
||||
|
||||
__ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
|
||||
__ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object
|
||||
STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
|
||||
|
@ -4063,6 +4063,9 @@ class TypeFeedbackCells: public FixedArray {
|
||||
|
||||
// Casting.
|
||||
static inline TypeFeedbackCells* cast(Object* obj);
|
||||
|
||||
static const int kForInFastCaseMarker = 0;
|
||||
static const int kForInSlowCaseMarker = 1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,6 +154,13 @@ bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) {
|
||||
}
|
||||
|
||||
|
||||
bool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) {
|
||||
Handle<Object> value = GetInfo(stmt->PrepareId());
|
||||
return value->IsSmi() &&
|
||||
Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker;
|
||||
}
|
||||
|
||||
|
||||
Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
|
||||
ASSERT(LoadIsMonomorphicNormal(expr));
|
||||
Handle<Object> map_or_code = GetInfo(expr->id());
|
||||
@ -659,9 +666,10 @@ void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) {
|
||||
for (int i = 0; i < cache->CellCount(); i++) {
|
||||
unsigned ast_id = cache->AstId(i)->value();
|
||||
Object* value = cache->Cell(i)->value();
|
||||
if (value->IsJSFunction() &&
|
||||
if (value->IsSmi() ||
|
||||
(value->IsJSFunction() &&
|
||||
!CanRetainOtherContext(JSFunction::cast(value),
|
||||
*global_context_)) {
|
||||
*global_context_))) {
|
||||
SetInfo(ast_id, value);
|
||||
}
|
||||
}
|
||||
|
@ -228,6 +228,7 @@ class Expression;
|
||||
class Property;
|
||||
class SmallMapList;
|
||||
class UnaryOperation;
|
||||
class ForInStatement;
|
||||
|
||||
|
||||
class TypeFeedbackOracle BASE_EMBEDDED {
|
||||
@ -243,6 +244,8 @@ class TypeFeedbackOracle BASE_EMBEDDED {
|
||||
bool CallIsMonomorphic(Call* expr);
|
||||
bool CallNewIsMonomorphic(CallNew* expr);
|
||||
|
||||
bool IsForInFastCase(ForInStatement* expr);
|
||||
|
||||
Handle<Map> LoadMonomorphicReceiverType(Property* expr);
|
||||
Handle<Map> StoreMonomorphicReceiverType(Expression* expr);
|
||||
|
||||
|
@ -969,6 +969,16 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
||||
// We got a fixed array in register rax. Iterate through that.
|
||||
Label non_proxy;
|
||||
__ bind(&fixed_array);
|
||||
|
||||
Handle<JSGlobalPropertyCell> cell =
|
||||
isolate()->factory()->NewJSGlobalPropertyCell(
|
||||
Handle<Object>(
|
||||
Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker)));
|
||||
RecordTypeFeedbackCell(stmt->PrepareId(), cell);
|
||||
__ LoadHeapObject(rbx, cell);
|
||||
__ Move(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset),
|
||||
Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker));
|
||||
|
||||
__ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check
|
||||
__ movq(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
|
||||
STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
|
||||
|
Loading…
Reference in New Issue
Block a user