blob: bcf37ae637d06c39646e5c05f7e98aa1497638b7 [file] [log] [blame]
danno@chromium.orgf005df62013-04-30 16:36:45 +00001// Copyright 2013 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// Flags: --track-fields --track-double-fields --allow-natives-syntax
29
30// Test transitions caused by changes to field representations.
31
32function create_smi_object() {
33 var o = {};
34 o.x = 1;
35 o.y = 2;
36 o.z = 3;
37 return o;
38}
39
40var o1 = create_smi_object();
41var o2 = create_smi_object();
42
43// o1,o2 are smi, smi, smi
44assertTrue(%HaveSameMap(o1, o2));
45o1.y = 1.3;
46// o1 is smi, double, smi
47assertFalse(%HaveSameMap(o1, o2));
48o2.y = 1.5;
49// o2 is smi, double, smi
50assertTrue(%HaveSameMap(o1, o2));
51
52// o3 is initialized as smi, double, smi
53var o3 = create_smi_object();
54assertTrue(%HaveSameMap(o1, o3));
55
56function set_large(o, v) {
57 o.x01 = v; o.x02 = v; o.x03 = v; o.x04 = v; o.x05 = v; o.x06 = v; o.x07 = v;
58 o.x08 = v; o.x09 = v; o.x10 = v; o.x11 = v; o.x12 = v; o.x13 = v; o.x14 = v;
59 o.x15 = v; o.x16 = v; o.x17 = v; o.x18 = v; o.x19 = v; o.x20 = v; o.x21 = v;
60 o.x22 = v; o.x23 = v; o.x24 = v; o.x25 = v; o.x26 = v; o.x27 = v; o.x28 = v;
61 o.x29 = v; o.x30 = v; o.x31 = v; o.x32 = v; o.x33 = v; o.x34 = v; o.x35 = v;
62 o.x36 = v; o.x37 = v; o.x38 = v; o.x39 = v; o.x40 = v; o.x41 = v; o.x42 = v;
63 o.y01 = v; o.y02 = v; o.y03 = v; o.y04 = v; o.y05 = v; o.y06 = v; o.y07 = v;
64 o.y08 = v; o.y09 = v; o.y10 = v; o.y11 = v; o.y12 = v; o.y13 = v; o.y14 = v;
65 o.y15 = v; o.y16 = v; o.y17 = v; o.y18 = v; o.y19 = v; o.y20 = v; o.y21 = v;
66}
67
68// Check that large object migrations work.
69var o4 = {};
70// All smi.
71set_large(o4, 0);
72assertTrue(%HasFastProperties(o4));
73// All double.
74set_large(o4, 1.5);
75// o5 is immediately allocated with doubles.
76var o5 = {};
77set_large(o5, 0);
78assertTrue(%HaveSameMap(o4, o5));
79
80function create_smi_object2() {
81 var o = {};
82 o.a = 1;
83 o.b = 2;
84 o.c = 3;
85 return o;
86}
87
88// All smi
89var o6 = create_smi_object2();
90var o7 = create_smi_object2();
91
92assertTrue(%HaveSameMap(o6, o7));
93// Smi, double, smi.
94o6.b = 1.5;
95assertFalse(%HaveSameMap(o6, o7));
96// Smi, double, object.
97o7.c = {};
98assertFalse(%HaveSameMap(o6, o7));
99// Smi, double, object.
100o6.c = {};
101assertTrue(%HaveSameMap(o6, o7));
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000102
103function poly_load(o, b) {
104 var v = o.field;
105 if (b) {
106 return v + 10;
107 }
108 return o;
109}
110
111var of1 = {a:0};
112of1.field = {};
113var of2 = {b:0};
114of2.field = 10;
115
116poly_load(of1, false);
117poly_load(of1, false);
118poly_load(of2, true);
119%OptimizeFunctionOnNextCall(poly_load);
120assertEquals("[object Object]10", poly_load(of1, true));
121
122// Ensure small object literals with doubles do not share double storage.
123function object_literal() { return {"a":1.5}; }
124var o8 = object_literal();
125var o9 = object_literal();
126o8.a = 4.6
127assertEquals(1.5, o9.a);
128
129// Ensure double storage is not leaked in the case of polymorphic loads.
130function load_poly(o) {
131 return o.a;
132}
133
134var o10 = { "a": 1.6 };
135var o11 = { "b": 1, "a": 1.7 };
136load_poly(o10);
137load_poly(o10);
138load_poly(o11);
139%OptimizeFunctionOnNextCall(load_poly);
140var val = load_poly(o10);
141o10.a = 19.5;
142assertFalse(o10.a == val);
143
144// Ensure polymorphic loads only go monomorphic when the representations are
145// compatible.
146
147// Check polymorphic load from double + object fields.
148function load_mono(o) {
149 return o.a1;
150}
151
152var object = {"x": 1};
153var o10 = { "a1": 1.6 };
154var o11 = { "a1": object, "b": 1 };
155load_mono(o10);
156load_mono(o10);
157load_mono(o11);
158%OptimizeFunctionOnNextCall(load_mono);
159assertEquals(object, load_mono(o11));
160
161// Check polymorphic load from smi + object fields.
162function load_mono2(o) {
163 return o.a2;
164}
165
166var o12 = { "a2": 5 };
167var o13 = { "a2": object, "b": 1 };
168load_mono2(o12);
169load_mono2(o12);
170load_mono2(o13);
171%OptimizeFunctionOnNextCall(load_mono2);
172assertEquals(object, load_mono2(o13));
173
174// Check polymorphic load from double + double fields.
175function load_mono3(o) {
176 return o.a3;
177}
178
179var o14 = { "a3": 1.6 };
180var o15 = { "a3": 1.8, "b": 1 };
181load_mono3(o14);
182load_mono3(o14);
183load_mono3(o15);
184%OptimizeFunctionOnNextCall(load_mono3);
185assertEquals(1.6, load_mono3(o14));
186assertEquals(1.8, load_mono3(o15));
187
188// Check that JSON parsing respects existing representations.
189var o16 = JSON.parse('{"a":1.5}');
190var o17 = JSON.parse('{"a":100}');
191assertTrue(%HaveSameMap(o16, o17));
192var o17_a = o17.a;
193assertEquals(100, o17_a);
194o17.a = 200;
195assertEquals(100, o17_a);
196assertEquals(200, o17.a);
197
198// Ensure normalizing results in ignored representations.
199var o18 = {};
200o18.field1 = 100;
201o18.field2 = 1;
202o18.to_delete = 100;
203
204var o19 = {};
205o19.field1 = 100;
206o19.field2 = 1.6;
207o19.to_delete = 100;
208
209assertFalse(%HaveSameMap(o18, o19));
210
211delete o18.to_delete;
212delete o19.to_delete;
213
214assertTrue(%HaveSameMap(o18, o19));
215assertEquals(1, o18.field2);
216assertEquals(1.6, o19.field2);
217
218// Test megamorphic keyed stub behaviour in combination with representations.
219var some_object20 = {"a":1};
220var o20 = {};
221o20.smi = 1;
222o20.dbl = 1.5;
223o20.obj = some_object20;
224
225function keyed_load(o, k) {
226 return o[k];
227}
228
229function keyed_store(o, k, v) {
230 return o[k] = v;
231}
232
233var smi20 = keyed_load(o20, "smi");
234var dbl20 = keyed_load(o20, "dbl");
235var obj20 = keyed_load(o20, "obj");
236keyed_load(o20, "smi");
237keyed_load(o20, "dbl");
238keyed_load(o20, "obj");
239keyed_load(o20, "smi");
240keyed_load(o20, "dbl");
241keyed_load(o20, "obj");
242
243assertEquals(1, smi20);
244assertEquals(1.5, dbl20);
245assertEquals(some_object20, obj20);
246
247keyed_store(o20, "smi", 100);
248keyed_store(o20, "dbl", 100);
249keyed_store(o20, "obj", 100);
250keyed_store(o20, "smi", 100);
251keyed_store(o20, "dbl", 100);
252keyed_store(o20, "obj", 100);
253keyed_store(o20, "smi", 100);
254keyed_store(o20, "dbl", 100);
255keyed_store(o20, "obj", 100);
256
257assertEquals(1, smi20);
258assertEquals(1.5, dbl20);
259assertEquals(some_object20, obj20);
260
261assertEquals(100, o20.smi);
262assertEquals(100, o20.dbl);
263assertEquals(100, o20.dbl);