X87: [for-in] Sanitize for-in optimizations and fix bailout points.

port f48bf12f5e (r33426)

  original commit message:
  The PrepareId bailout location was used incorrectly in Crankshaft and,
  as it turns out, is not required anyway (once you do it right). Also
  there was some premature optimization going on with the CheckEnumCache
  (trying to load null from roots only once), plus we can be smarter about
  the null/undefined check anyway.

  The idea behind this changes is to prepare unification of the two
  different ForInPrepare implementations that we now have, with the end
  result being that we only use the new implementation that was recently
  added for the interpreter.

BUG=

Review URL: https://codereview.chromium.org/1611113002

Cr-Commit-Position: refs/heads/master@{#33428}
This commit is contained in:
zhengxing.li 2016-01-21 02:19:28 -08:00 committed by Commit bot
parent 1c6a818efb
commit 512d8286c9
2 changed files with 10 additions and 24 deletions

View File

@ -5889,12 +5889,6 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
DCHECK(ToRegister(instr->context()).is(esi));
__ test(eax, Immediate(kSmiTagMask));
DeoptimizeIf(zero, instr, Deoptimizer::kSmi);
STATIC_ASSERT(JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE);
__ CmpObjectType(eax, JS_PROXY_TYPE, ecx);
DeoptimizeIf(below_equal, instr, Deoptimizer::kWrongInstanceType);
Label use_cache, call_runtime;
__ CheckEnumCache(&call_runtime);
@ -5906,10 +5900,6 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
__ bind(&call_runtime);
__ push(eax);
CallRuntime(Runtime::kGetPropertyNamesFast, instr);
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
isolate()->factory()->meta_map());
DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap);
__ bind(&use_cache);
}

View File

@ -969,22 +969,20 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
ForIn loop_statement(this, stmt);
increment_loop_depth();
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
// Get the object to enumerate over.
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ cmp(eax, isolate()->factory()->undefined_value());
__ j(equal, &exit);
__ cmp(eax, isolate()->factory()->null_value());
__ j(equal, &exit);
PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
// Convert the object to a JS object.
// If the object is null or undefined, skip over the loop, otherwise convert
// it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
Label convert, done_convert;
__ JumpIfSmi(eax, &convert, Label::kNear);
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
__ j(above_equal, &done_convert, Label::kNear);
__ cmp(eax, isolate()->factory()->undefined_value());
__ j(equal, &exit);
__ cmp(eax, isolate()->factory()->null_value());
__ j(equal, &exit);
__ bind(&convert);
ToObjectStub stub(isolate());
__ CallStub(&stub);
@ -992,15 +990,13 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
__ push(eax);
// Check for proxies.
Label call_runtime, use_cache, fixed_array;
__ CmpObjectType(eax, JS_PROXY_TYPE, ecx);
__ j(equal, &call_runtime);
// Check cache validity in generated code. This is a fast case for
// the JSObject::IsSimpleEnum cache validity checks. If we cannot
// guarantee cache validity, call the runtime system to check cache
// validity or get the property names in a fixed array.
// Note: Proxies never have an enum cache, so will always take the
// slow path.
Label call_runtime, use_cache, fixed_array;
__ CheckEnumCache(&call_runtime);
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));