[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}
This commit is contained in:
verwaest 2016-03-01 10:16:33 -08:00 committed by Commit bot
parent 2a9a770c2a
commit 8016a2d53f
2 changed files with 54 additions and 34 deletions

View File

@ -8752,6 +8752,25 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
} }
// Try to inline calls like Math.* as operations in the calling function. // Try to inline calls like Math.* as operations in the calling function.
switch (id) { 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<HCheckMapValue>(receiver, cache->map());
ast_context()->ReturnValue(graph()->GetConstantTrue());
return true;
}
case kStringCharCodeAt: case kStringCharCodeAt:
case kStringCharAt: case kStringCharAt:
if (argument_count == 2) { if (argument_count == 2) {

View File

@ -6556,40 +6556,41 @@ class Script: public Struct {
// //
// Installation of ids for the selected builtin functions is handled // Installation of ids for the selected builtin functions is handled
// by the bootstrapper. // by the bootstrapper.
#define FUNCTIONS_WITH_ID_LIST(V) \ #define FUNCTIONS_WITH_ID_LIST(V) \
V(Array.prototype, indexOf, ArrayIndexOf) \ V(Array.prototype, indexOf, ArrayIndexOf) \
V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \ V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
V(Array.prototype, push, ArrayPush) \ V(Array.prototype, push, ArrayPush) \
V(Array.prototype, pop, ArrayPop) \ V(Array.prototype, pop, ArrayPop) \
V(Array.prototype, shift, ArrayShift) \ V(Array.prototype, shift, ArrayShift) \
V(Function.prototype, apply, FunctionApply) \ V(Function.prototype, apply, FunctionApply) \
V(Function.prototype, call, FunctionCall) \ V(Function.prototype, call, FunctionCall) \
V(String.prototype, charCodeAt, StringCharCodeAt) \ V(Object.prototype, hasOwnProperty, ObjectHasOwnProperty) \
V(String.prototype, charAt, StringCharAt) \ V(String.prototype, charCodeAt, StringCharCodeAt) \
V(String.prototype, concat, StringConcat) \ V(String.prototype, charAt, StringCharAt) \
V(String.prototype, toLowerCase, StringToLowerCase) \ V(String.prototype, concat, StringConcat) \
V(String.prototype, toUpperCase, StringToUpperCase) \ V(String.prototype, toLowerCase, StringToLowerCase) \
V(String, fromCharCode, StringFromCharCode) \ V(String.prototype, toUpperCase, StringToUpperCase) \
V(Math, random, MathRandom) \ V(String, fromCharCode, StringFromCharCode) \
V(Math, floor, MathFloor) \ V(Math, random, MathRandom) \
V(Math, round, MathRound) \ V(Math, floor, MathFloor) \
V(Math, ceil, MathCeil) \ V(Math, round, MathRound) \
V(Math, abs, MathAbs) \ V(Math, ceil, MathCeil) \
V(Math, log, MathLog) \ V(Math, abs, MathAbs) \
V(Math, exp, MathExp) \ V(Math, log, MathLog) \
V(Math, sqrt, MathSqrt) \ V(Math, exp, MathExp) \
V(Math, pow, MathPow) \ V(Math, sqrt, MathSqrt) \
V(Math, max, MathMax) \ V(Math, pow, MathPow) \
V(Math, min, MathMin) \ V(Math, max, MathMax) \
V(Math, cos, MathCos) \ V(Math, min, MathMin) \
V(Math, sin, MathSin) \ V(Math, cos, MathCos) \
V(Math, tan, MathTan) \ V(Math, sin, MathSin) \
V(Math, acos, MathAcos) \ V(Math, tan, MathTan) \
V(Math, asin, MathAsin) \ V(Math, acos, MathAcos) \
V(Math, atan, MathAtan) \ V(Math, asin, MathAsin) \
V(Math, atan2, MathAtan2) \ V(Math, atan, MathAtan) \
V(Math, imul, MathImul) \ V(Math, atan2, MathAtan2) \
V(Math, clz32, MathClz32) \ V(Math, imul, MathImul) \
V(Math, clz32, MathClz32) \
V(Math, fround, MathFround) V(Math, fround, MathFround)
#define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \ #define ATOMIC_FUNCTIONS_WITH_ID_LIST(V) \