Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Redistribution and use in source and binary forms, with or without
3 : // modification, are permitted provided that the following conditions are
4 : // met:
5 : //
6 : // * Redistributions of source code must retain the above copyright
7 : // notice, this list of conditions and the following disclaimer.
8 : // * Redistributions in binary form must reproduce the above
9 : // copyright notice, this list of conditions and the following
10 : // disclaimer in the documentation and/or other materials provided
11 : // with the distribution.
12 : // * Neither the name of Google Inc. nor the names of its
13 : // contributors may be used to endorse or promote products derived
14 : // from this software without specific prior written permission.
15 : //
16 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 :
28 : #ifndef V8_TEST_CCTEST_TYPES_H_
29 : #define V8_TEST_CCTEST_TYPES_H_
30 :
31 : #include "src/base/utils/random-number-generator.h"
32 : #include "src/heap/factory.h"
33 : #include "src/isolate.h"
34 : #include "src/v8.h"
35 :
36 : namespace v8 {
37 : namespace internal {
38 : namespace compiler {
39 :
40 352 : class Types {
41 : public:
42 176 : Types(Zone* zone, Isolate* isolate, v8::base::RandomNumberGenerator* rng)
43 176 : : zone_(zone), js_heap_broker_(isolate, zone), rng_(rng) {
44 : #define DECLARE_TYPE(name, value) \
45 : name = Type::name(); \
46 : types.push_back(name);
47 176 : PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
48 : #undef DECLARE_TYPE
49 :
50 176 : SignedSmall = Type::SignedSmall();
51 176 : UnsignedSmall = Type::UnsignedSmall();
52 :
53 : object_map =
54 176 : isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
55 :
56 176 : smi = handle(Smi::FromInt(666), isolate);
57 176 : boxed_smi = isolate->factory()->NewHeapNumber(666);
58 176 : signed32 = isolate->factory()->NewHeapNumber(0x40000000);
59 176 : float1 = isolate->factory()->NewHeapNumber(1.53);
60 176 : float2 = isolate->factory()->NewHeapNumber(0.53);
61 : // float3 is identical to float1 in order to test that OtherNumberConstant
62 : // types are equal by double value and not by handle pointer value.
63 176 : float3 = isolate->factory()->NewHeapNumber(1.53);
64 176 : object1 = isolate->factory()->NewJSObjectFromMap(object_map);
65 176 : object2 = isolate->factory()->NewJSObjectFromMap(object_map);
66 176 : array = isolate->factory()->NewJSArray(20);
67 176 : uninitialized = isolate->factory()->uninitialized_value();
68 176 : SmiConstant = Type::NewConstant(js_heap_broker(), smi, zone);
69 176 : Signed32Constant = Type::NewConstant(js_heap_broker(), signed32, zone);
70 :
71 176 : ObjectConstant1 = Type::HeapConstant(js_heap_broker(), object1, zone);
72 176 : ObjectConstant2 = Type::HeapConstant(js_heap_broker(), object2, zone);
73 176 : ArrayConstant = Type::HeapConstant(js_heap_broker(), array, zone);
74 : UninitializedConstant =
75 176 : Type::HeapConstant(js_heap_broker(), uninitialized, zone);
76 :
77 352 : values.push_back(smi);
78 176 : values.push_back(boxed_smi);
79 176 : values.push_back(signed32);
80 176 : values.push_back(object1);
81 176 : values.push_back(object2);
82 176 : values.push_back(array);
83 176 : values.push_back(uninitialized);
84 176 : values.push_back(float1);
85 176 : values.push_back(float2);
86 176 : values.push_back(float3);
87 1936 : for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
88 3520 : types.push_back(Type::NewConstant(js_heap_broker(), *it, zone));
89 : }
90 :
91 352 : integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
92 352 : integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
93 352 : integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
94 352 : integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
95 3696 : for (int i = 0; i < 10; ++i) {
96 3520 : double x = rng_->NextInt();
97 3520 : integers.push_back(isolate->factory()->NewNumber(x));
98 3520 : x *= rng_->NextInt();
99 3520 : if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
100 : }
101 :
102 176 : Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, zone);
103 :
104 10736 : for (int i = 0; i < 30; ++i) {
105 10560 : types.push_back(Fuzz());
106 : }
107 176 : }
108 :
109 : Handle<i::Map> object_map;
110 :
111 : Handle<i::Smi> smi;
112 : Handle<i::HeapNumber> boxed_smi;
113 : Handle<i::HeapNumber> signed32;
114 : Handle<i::HeapNumber> float1;
115 : Handle<i::HeapNumber> float2;
116 : Handle<i::HeapNumber> float3;
117 : Handle<i::JSObject> object1;
118 : Handle<i::JSObject> object2;
119 : Handle<i::JSArray> array;
120 : Handle<i::Oddball> uninitialized;
121 :
122 : #define DECLARE_TYPE(name, value) Type name;
123 : PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
124 : #undef DECLARE_TYPE
125 :
126 : Type SignedSmall;
127 : Type UnsignedSmall;
128 :
129 : Type SmiConstant;
130 : Type Signed32Constant;
131 : Type ObjectConstant1;
132 : Type ObjectConstant2;
133 : Type ArrayConstant;
134 : Type UninitializedConstant;
135 :
136 : Type Integer;
137 :
138 : typedef std::vector<Type> TypeVector;
139 : typedef std::vector<Handle<i::Object> > ValueVector;
140 :
141 : TypeVector types;
142 : ValueVector values;
143 : ValueVector integers; // "Integer" values used for range limits.
144 :
145 : Type NewConstant(Handle<i::Object> value) {
146 981 : return Type::NewConstant(js_heap_broker(), value, zone_);
147 : }
148 :
149 : Type HeapConstant(Handle<i::HeapObject> value) {
150 : return Type::HeapConstant(js_heap_broker(), value, zone_);
151 : }
152 :
153 361168 : Type Range(double min, double max) { return Type::Range(min, max, zone_); }
154 :
155 1181913 : Type Union(Type t1, Type t2) { return Type::Union(t1, t2, zone_); }
156 :
157 2242165 : Type Intersect(Type t1, Type t2) { return Type::Intersect(t1, t2, zone_); }
158 :
159 : Type Random() { return types[rng_->NextInt(static_cast<int>(types.size()))]; }
160 :
161 20906640 : Type Fuzz(int depth = 4) {
162 20906640 : switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
163 : case 0: { // bitset
164 : #define COUNT_BITSET_TYPES(type, value) +1
165 : int n = 0 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES);
166 : #undef COUNT_BITSET_TYPES
167 : // Pick a bunch of named bitsets and return their intersection.
168 : Type result = Type::Any();
169 12238261 : for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) {
170 9638920 : int j = rng_->NextInt(n);
171 : #define PICK_BITSET_TYPE(type, value) \
172 : if (j-- == 0) { \
173 : Type tmp = Type::Intersect(result, Type::type(), zone_); \
174 : if (tmp.Is(Type::None()) && i != 0) { \
175 : break; \
176 : } else { \
177 : result = tmp; \
178 : continue; \
179 : } \
180 : }
181 19277840 : PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
182 : #undef PICK_BITSET_TYPE
183 : }
184 5397960 : return result;
185 : }
186 : case 1: { // constant
187 5403573 : int i = rng_->NextInt(static_cast<int>(values.size()));
188 10807146 : return Type::NewConstant(js_heap_broker(), values[i], zone_);
189 : }
190 : case 2: { // range
191 5468739 : int i = rng_->NextInt(static_cast<int>(integers.size()));
192 5468739 : int j = rng_->NextInt(static_cast<int>(integers.size()));
193 5468739 : double min = integers[i]->Number();
194 5468739 : double max = integers[j]->Number();
195 5468739 : if (min > max) std::swap(min, max);
196 5468739 : return Type::Range(min, max, zone_);
197 : }
198 : default: { // union
199 4636368 : int n = rng_->NextInt(10);
200 4636368 : Type type = None;
201 46312726 : for (int i = 0; i < n; ++i) {
202 20838179 : Type operand = Fuzz(depth - 1);
203 20838179 : type = Type::Union(type, operand, zone_);
204 : }
205 4636368 : return type;
206 : }
207 : }
208 : UNREACHABLE();
209 : }
210 :
211 : Zone* zone() { return zone_; }
212 5403894 : JSHeapBroker* js_heap_broker() { return &js_heap_broker_; }
213 :
214 : private:
215 : Zone* zone_;
216 : JSHeapBroker js_heap_broker_;
217 : v8::base::RandomNumberGenerator* rng_;
218 : };
219 :
220 : } // namespace compiler
221 : } // namespace internal
222 : } // namespace v8
223 :
224 : #endif
|