From 8016a2d53f7d4ea3e35b3a43c7097412e6b38c6a Mon Sep 17 00:00:00 2001 From: verwaest Date: Tue, 1 Mar 2016 10:16:33 -0800 Subject: [PATCH] [crankshaft] Inline hasOwnProperty when used in fast-case for-in e.g., for (var k in o) { if (!o.hasOwnProperty(k)) continue; ... } without enumerable properties on the prototype chain of o. BUG= Committed: https://crrev.com/dec80752eb344dfeb85588e61ac0afd22b11aadb Cr-Commit-Position: refs/heads/master@{#34379} Review URL: https://codereview.chromium.org/1742253002 Cr-Commit-Position: refs/heads/master@{#34405} --- src/crankshaft/hydrogen.cc | 19 +++++++++++ src/objects.h | 69 +++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc index 8ff3f3ba3f..0fa8daa641 100644 --- a/src/crankshaft/hydrogen.cc +++ b/src/crankshaft/hydrogen.cc @@ -8752,6 +8752,25 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( } // Try to inline calls like Math.* as operations in the calling function. switch (id) { + case kObjectHasOwnProperty: { + // It's not safe to look through the phi for elements if we're compiling + // for osr. + if (top_info()->is_osr()) return false; + if (argument_count != 2) return false; + HValue* key = Top(); + if (!key->IsLoadKeyed()) return false; + HValue* elements = HLoadKeyed::cast(key)->elements(); + if (!elements->IsPhi() || elements->OperandCount() != 1) return false; + if (!elements->OperandAt(0)->IsForInCacheArray()) return false; + HForInCacheArray* cache = HForInCacheArray::cast(elements->OperandAt(0)); + HValue* receiver = environment()->ExpressionStackAt(1); + if (!receiver->IsPhi() || receiver->OperandCount() != 1) return false; + if (cache->enumerable() != receiver->OperandAt(0)) return false; + Drop(3); // key, receiver, function + Add(receiver, cache->map()); + ast_context()->ReturnValue(graph()->GetConstantTrue()); + return true; + } case kStringCharCodeAt: case kStringCharAt: if (argument_count == 2) { diff --git a/src/objects.h b/src/objects.h index 1a90048690..836fea6426 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6556,40 +6556,41 @@ class Script: public Struct { // // Installation of ids for the selected builtin functions is handled // by the bootstrapper. -#define FUNCTIONS_WITH_ID_LIST(V) \ - V(Array.prototype, indexOf, ArrayIndexOf) \ - V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \ - V(Array.prototype, push, ArrayPush) \ - V(Array.prototype, pop, ArrayPop) \ - V(Array.prototype, shift, ArrayShift) \ - V(Function.prototype, apply, FunctionApply) \ - V(Function.prototype, call, FunctionCall) \ - V(String.prototype, charCodeAt, StringCharCodeAt) \ - V(String.prototype, charAt, StringCharAt) \ - V(String.prototype, concat, StringConcat) \ - V(String.prototype, toLowerCase, StringToLowerCase) \ - V(String.prototype, toUpperCase, StringToUpperCase) \ - V(String, fromCharCode, StringFromCharCode) \ - V(Math, random, MathRandom) \ - V(Math, floor, MathFloor) \ - V(Math, round, MathRound) \ - V(Math, ceil, MathCeil) \ - V(Math, abs, MathAbs) \ - V(Math, log, MathLog) \ - V(Math, exp, MathExp) \ - V(Math, sqrt, MathSqrt) \ - V(Math, pow, MathPow) \ - V(Math, max, MathMax) \ - V(Math, min, MathMin) \ - V(Math, cos, MathCos) \ - V(Math, sin, MathSin) \ - V(Math, tan, MathTan) \ - V(Math, acos, MathAcos) \ - V(Math, asin, MathAsin) \ - V(Math, atan, MathAtan) \ - V(Math, atan2, MathAtan2) \ - V(Math, imul, MathImul) \ - V(Math, clz32, MathClz32) \ +#define FUNCTIONS_WITH_ID_LIST(V) \ + V(Array.prototype, indexOf, ArrayIndexOf) \ + V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \ + V(Array.prototype, push, ArrayPush) \ + V(Array.prototype, pop, ArrayPop) \ + V(Array.prototype, shift, ArrayShift) \ + V(Function.prototype, apply, FunctionApply) \ + V(Function.prototype, call, FunctionCall) \ + V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \ + V(String.prototype, charCodeAt, StringCharCodeAt) \ + V(String.prototype, charAt, StringCharAt) \ + V(String.prototype, concat, StringConcat) \ + V(String.prototype, toLowerCase, StringToLowerCase) \ + V(String.prototype, toUpperCase, StringToUpperCase) \ + V(String, fromCharCode, StringFromCharCode) \ + V(Math, random, MathRandom) \ + V(Math, floor, MathFloor) \ + V(Math, round, MathRound) \ + V(Math, ceil, MathCeil) \ + V(Math, abs, MathAbs) \ + V(Math, log, MathLog) \ + V(Math, exp, MathExp) \ + V(Math, sqrt, MathSqrt) \ + V(Math, pow, MathPow) \ + V(Math, max, MathMax) \ + V(Math, min, MathMin) \ + V(Math, cos, MathCos) \ + V(Math, sin, MathSin) \ + V(Math, tan, MathTan) \ + V(Math, acos, MathAcos) \ + V(Math, asin, MathAsin) \ + V(Math, atan, MathAtan) \ + V(Math, atan2, MathAtan2) \ + V(Math, imul, MathImul) \ + V(Math, clz32, MathClz32) \ V(Math, fround, MathFround) #define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \