Skip to content

Commit 83dfb44

Browse files
mhorowitzfacebook-github-bot
authored andcommitted
Don't check the for-in cache for non-cacheable objects.
Summary: Previously, if a Proxy shared a HiddenClass with an object in the ForIn cache, the code would try to walk the prototype chain on the Proxy, which triggers an assert. Also split the slow test out of for_in.js. Reviewed By: tmikov Differential Revision: D24061305 fbshipit-source-id: aef2b3e4b00943a14a6cee85c351eef7788f9b9b
1 parent d82358b commit 83dfb44

3 files changed

Lines changed: 48 additions & 30 deletions

File tree

lib/VM/JSObject.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3141,19 +3141,22 @@ CallResult<Handle<BigStorage>> getForInPropertyNames(
31413141
Handle<HiddenClass> clazz(runtime, obj->getClass(runtime));
31423142

31433143
// Fast case: Check the cache.
3144-
MutableHandle<BigStorage> arr(runtime, clazz->getForInCache(runtime));
3145-
if (arr) {
3146-
beginIndex = matchesProtoClasses(runtime, obj, arr);
3147-
if (beginIndex) {
3148-
// Cache is valid for this object, so use it.
3149-
endIndex = arr->size();
3150-
return arr;
3151-
}
3152-
// Invalid for this object. We choose to clear the cache since the
3153-
// changes to the prototype chain probably affect other objects too.
3154-
clazz->clearForInCache(runtime);
3155-
// Clear arr to slightly reduce risk of OOM from allocation below.
3156-
arr = nullptr;
3144+
MutableHandle<BigStorage> arr(runtime);
3145+
if (obj->shouldCacheForIn(runtime)) {
3146+
arr = clazz->getForInCache(runtime);
3147+
if (arr) {
3148+
beginIndex = matchesProtoClasses(runtime, obj, arr);
3149+
if (beginIndex) {
3150+
// Cache is valid for this object, so use it.
3151+
endIndex = arr->size();
3152+
return arr;
3153+
}
3154+
// Invalid for this object. We choose to clear the cache since the
3155+
// changes to the prototype chain probably affect other objects too.
3156+
clazz->clearForInCache(runtime);
3157+
// Clear arr to slightly reduce risk of OOM from allocation below.
3158+
arr = nullptr;
3159+
}
31573160
}
31583161

31593162
// Slow case: Build the array of properties.

test/hermes/for_in.js

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
// RUN: %hermes -O -gc-sanitize-handles=0 -target=HBC %s | %FileCheck --match-full-lines %s
9-
// RUN: %hermes -O -target=HBC -emit-binary -out %t.hbc %s && %hermes -gc-sanitize-handles=0 %t.hbc | %FileCheck --match-full-lines %s
10-
// REQUIRES: !slow_debug
11-
12-
// This test took over 10 minutes with HandleSan, so -gc-sanitize-handles=0 is
13-
// passed to reduce the chances of tests timing out.
8+
// RUN: %hermes -O -target=HBC %s | %FileCheck --match-full-lines %s
9+
// RUN: %hermes -O -target=HBC -emit-binary -out %t.hbc %s && %hermes %t.hbc | %FileCheck --match-full-lines %s
1410

1511
// Simple case
1612
var x = {};
@@ -113,14 +109,8 @@ for (var y in x) {
113109
//CHECK: s4 4
114110
//CHECK: s5 5
115111

116-
// Large array (doesn't fit in single segment)
117-
var a = []
118-
for (var i = 0; i < 1000*1000; ++i) {
119-
a[i] = i;
120-
}
121-
var t = 0;
122-
for (var p in a) {
123-
t += 1;
124-
}
125-
print(t);
126-
//CHECK: 1000000
112+
// Don't probe parent chain of non-cacheable objects (proxy will assert)
113+
// 1. This creates a for-in cache entry for a particular hidden class
114+
for (var k in Number(0)) {}
115+
// 2. This Proxy uses the same hidden cache object internally.
116+
for (var k in new Proxy({},{})) {}

test/hermes/for_in_bigloop.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// RUN: %hermes -O -gc-sanitize-handles=0 -target=HBC %s | %FileCheck --match-full-lines %s
9+
// RUN: %hermes -O -target=HBC -emit-binary -out %t.hbc %s && %hermes -gc-sanitize-handles=0 %t.hbc | %FileCheck --match-full-lines %s
10+
// REQUIRES: !slow_debug
11+
12+
// This test took over 10 minutes with HandleSan, so -gc-sanitize-handles=0 is
13+
// passed to reduce the chances of tests timing out.
14+
15+
// Large array (doesn't fit in single segment)
16+
var a = []
17+
for (var i = 0; i < 1000*1000; ++i) {
18+
a[i] = i;
19+
}
20+
var t = 0;
21+
for (var p in a) {
22+
t += 1;
23+
}
24+
print(t);
25+
//CHECK: 1000000

0 commit comments

Comments
 (0)