1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/init/v8.h"
6
7 #include "test/cctest/cctest.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace test_usecounters {
12
13 int* global_use_counts = nullptr;
14
MockUseCounterCallback(v8::Isolate * isolate,v8::Isolate::UseCounterFeature feature)15 void MockUseCounterCallback(v8::Isolate* isolate,
16 v8::Isolate::UseCounterFeature feature) {
17 ++global_use_counts[feature];
18 }
19
TEST(AssigmentExpressionLHSIsCall)20 TEST(AssigmentExpressionLHSIsCall) {
21 v8::Isolate* isolate = CcTest::isolate();
22 v8::HandleScope scope(isolate);
23 LocalContext env;
24 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
25 global_use_counts = use_counts;
26 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
27
28 // AssignmentExpressions whose LHS is not a call do not increment counters
29 CompileRun("function f(){ a = 0; a()[b] = 0; }");
30 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
31 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
32 CompileRun("function f(){ ++a; ++a()[b]; }");
33 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
34 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
35 CompileRun("function f(){ 'use strict'; a = 0; a()[b] = 0; }");
36 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
37 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
38 CompileRun("function f(){ 'use strict'; ++a; ++a()[b]; }");
39 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
40 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
41
42 // AssignmentExpressions whose LHS is a call increment appropriate counters
43 CompileRun("function f(){ a() = 0; }");
44 CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
45 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
46 use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
47 CompileRun("function f(){ 'use strict'; a() = 0; }");
48 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
49 CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
50 use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
51
52 // UpdateExpressions whose LHS is a call increment appropriate counters
53 CompileRun("function f(){ ++a(); }");
54 CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
55 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
56 use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
57 CompileRun("function f(){ 'use strict'; ++a(); }");
58 CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
59 CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
60 use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
61 }
62
TEST(RegExpMatchIsTrueishOnNonJSRegExp)63 TEST(RegExpMatchIsTrueishOnNonJSRegExp) {
64 v8::Isolate* isolate = CcTest::isolate();
65 v8::HandleScope scope(isolate);
66 LocalContext env;
67 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
68 global_use_counts = use_counts;
69 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
70
71 CompileRun("new RegExp(/./); new RegExp('');");
72 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp]);
73 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp]);
74
75 CompileRun("let p = { [Symbol.match]: true }; new RegExp(p);");
76 CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp]);
77 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp]);
78 }
79
TEST(RegExpMatchIsFalseishOnJSRegExp)80 TEST(RegExpMatchIsFalseishOnJSRegExp) {
81 v8::Isolate* isolate = CcTest::isolate();
82 v8::HandleScope scope(isolate);
83 LocalContext env;
84 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
85 global_use_counts = use_counts;
86 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
87
88 CompileRun("new RegExp(/./); new RegExp('');");
89 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp]);
90 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp]);
91
92 CompileRun("let p = /./; p[Symbol.match] = false; new RegExp(p);");
93 CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp]);
94 CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp]);
95 }
96
TEST(ObjectPrototypeHasElements)97 TEST(ObjectPrototypeHasElements) {
98 v8::Isolate* isolate = CcTest::isolate();
99 v8::HandleScope scope(isolate);
100 LocalContext env;
101 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
102 global_use_counts = use_counts;
103 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
104
105 CompileRun("var o = {}; o[1] = 2;");
106 CHECK_EQ(0, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
107
108 CompileRun("var o = {}; var p = {}; o.__proto__ = p; p[1] = 2;");
109 CHECK_EQ(0, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
110
111 CompileRun("Object.prototype[1] = 2;");
112 CHECK_EQ(1, use_counts[v8::Isolate::kObjectPrototypeHasElements]);
113 }
114
TEST(ArrayPrototypeHasElements)115 TEST(ArrayPrototypeHasElements) {
116 v8::Isolate* isolate = CcTest::isolate();
117 v8::HandleScope scope(isolate);
118 LocalContext env;
119 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
120 global_use_counts = use_counts;
121 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
122
123 CompileRun("var a = []; a[1] = 2;");
124 CHECK_EQ(0, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
125
126 CompileRun("var a = []; var p = []; a.__proto__ = p; p[1] = 2;");
127 CHECK_EQ(0, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
128
129 CompileRun("Array.prototype[1] = 2;");
130 CHECK_EQ(1, use_counts[v8::Isolate::kArrayPrototypeHasElements]);
131 }
132
133 } // namespace test_usecounters
134 } // namespace internal
135 } // namespace v8
136