The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / mjsunit / compiler / escape-analysis.js @ f230a1cf

History | View | Annotate | Download (8.58 KB)

1
// 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: --allow-natives-syntax --use-escape-analysis --expose-gc
29

    
30

    
31
// Test stores on a join path.
32
(function testJoin() {
33
  function constructor() {
34
    this.a = 0;
35
  }
36
  function join(mode, expected) {
37
    var object = new constructor();
38
    if (mode) {
39
      object.a = 1;
40
    } else {
41
      object.a = 2;
42
    }
43
    assertEquals(expected, object.a);
44
  }
45
  join(true, 1); join(true, 1);
46
  join(false, 2); join(false, 2);
47
  %OptimizeFunctionOnNextCall(join);
48
  join(true, 1); join(false, 2);
49
})();
50

    
51

    
52
// Test loads and stores inside a loop.
53
(function testLoop() {
54
  function constructor() {
55
    this.a = 0;
56
    this.b = 23;
57
  }
58
  function loop() {
59
    var object = new constructor();
60
    for (var i = 1; i < 10; i++) {
61
      object.a = object.a + i;
62
      assertEquals(i*(i+1)/2, object.a);
63
      assertEquals(23, object.b);
64
    }
65
    assertEquals(45, object.a);
66
    assertEquals(23, object.b);
67
  }
68
  loop(); loop();
69
  %OptimizeFunctionOnNextCall(loop);
70
  loop(); loop();
71
})();
72

    
73

    
74
// Test loads and stores inside nested loop.
75
(function testNested() {
76
  function constructor() {
77
    this.a = 0;
78
    this.b = 0;
79
    this.c = 23;
80
  }
81
  function nested() {
82
    var object = new constructor();
83
    for (var i = 1; i < 10; i++) {
84
      object.a = object.a + i;
85
      assertEquals(i*(i+1)/2, object.a);
86
      assertEquals((i-1)*6, object.b);
87
      assertEquals(23, object.c);
88
      for (var j = 1; j < 4; j++) {
89
        object.b = object.b + j;
90
        assertEquals(i*(i+1)/2, object.a);
91
        assertEquals((i-1)*6+j*(j+1)/2, object.b);
92
        assertEquals(23, object.c);
93
      }
94
      assertEquals(i*(i+1)/2, object.a);
95
      assertEquals(i*6, object.b);
96
      assertEquals(23, object.c);
97
    }
98
    assertEquals(45, object.a);
99
    assertEquals(54, object.b);
100
    assertEquals(23, object.c);
101
  }
102
  nested(); nested();
103
  %OptimizeFunctionOnNextCall(nested);
104
  nested(); nested();
105
})();
106

    
107

    
108
// Test deoptimization with captured objects in local variables.
109
(function testDeoptLocal() {
110
  var deopt = { deopt:false };
111
  function constructor1() {
112
    this.a = 1.0;
113
    this.b = 2.3;
114
    this.c = 3.0;
115
  }
116
  function constructor2(o) {
117
    this.d = o;
118
    this.e = 4.5;
119
  }
120
  function func() {
121
    var o1 = new constructor1();
122
    var o2 = new constructor2(o1);
123
    deopt.deopt;
124
    assertEquals(1.0, o1.a);
125
    assertEquals(2.3, o2.d.b);
126
    assertEquals(3.0, o2.d.c);
127
    assertEquals(4.5, o2.e);
128
  }
129
  func(); func();
130
  %OptimizeFunctionOnNextCall(func);
131
  func(); func();
132
  delete deopt.deopt;
133
  func(); func();
134
})();
135

    
136

    
137
// Test deoptimization with captured objects on operand stack.
138
(function testDeoptOperand() {
139
  var deopt = { deopt:false };
140
  function constructor1() {
141
    this.a = 1.0;
142
    this.b = 2.3;
143
    deopt.deopt;
144
    assertEquals(1.0, this.a);
145
    assertEquals(2.3, this.b);
146
    this.b = 2.7;
147
    this.c = 3.0;
148
    this.d = 4.5;
149
  }
150
  function constructor2() {
151
    this.e = 5.0;
152
    this.f = new constructor1();
153
    assertEquals(1.0, this.f.a);
154
    assertEquals(2.7, this.f.b);
155
    assertEquals(3.0, this.f.c);
156
    assertEquals(4.5, this.f.d);
157
    assertEquals(5.0, this.e);
158
    this.e = 5.9;
159
    this.g = 6.7;
160
  }
161
  function func() {
162
    var o = new constructor2();
163
    assertEquals(1.0, o.f.a);
164
    assertEquals(2.7, o.f.b);
165
    assertEquals(3.0, o.f.c);
166
    assertEquals(4.5, o.f.d);
167
    assertEquals(5.9, o.e);
168
    assertEquals(6.7, o.g);
169
  }
170
  func(); func();
171
  %OptimizeFunctionOnNextCall(func);
172
  func(); func();
173
  delete deopt.deopt;
174
  func(); func();
175
})();
176

    
177

    
178
// Test map checks on captured objects.
179
(function testMapCheck() {
180
  var sum = 0;
181
  function getter() { return 27; }
182
  function setter(v) { sum += v; }
183
  function constructor() {
184
    this.x = 23;
185
    this.y = 42;
186
  }
187
  function check(x, y) {
188
    var o = new constructor();
189
    assertEquals(x, o.x);
190
    assertEquals(y, o.y);
191
  }
192
  var monkey = Object.create(null, {
193
    x: { get:getter, set:setter },
194
    y: { get:getter, set:setter }
195
  });
196
  check(23, 42); check(23, 42);
197
  %OptimizeFunctionOnNextCall(check);
198
  check(23, 42); check(23, 42);
199
  constructor.prototype = monkey;
200
  check(27, 27); check(27, 27);
201
  assertEquals(130, sum);
202
})();
203

    
204

    
205
// Test OSR into a loop with captured objects.
206
(function testOSR() {
207
  function constructor() {
208
    this.a = 23;
209
  }
210
  function osr1(length) {
211
    assertEquals(23, (new constructor()).a);
212
    var result = 0;
213
    for (var i = 0; i < length; i++) {
214
      result = (result + i) % 99;
215
    }
216
    return result;
217
  }
218
  function osr2(length) {
219
    var result = 0;
220
    for (var i = 0; i < length; i++) {
221
      result = (result + i) % 99;
222
    }
223
    assertEquals(23, (new constructor()).a);
224
    return result;
225
  }
226
  function osr3(length) {
227
    var result = 0;
228
    var o = new constructor();
229
    for (var i = 0; i < length; i++) {
230
      result = (result + i) % 99;
231
    }
232
    assertEquals(23, o.a);
233
    return result;
234
  }
235
  function test(closure) {
236
    assertEquals(45, closure(10));
237
    assertEquals(45, closure(10));
238
    assertEquals(10, closure(50000));
239
  }
240
  test(osr1);
241
  test(osr2);
242
  test(osr3);
243
})();
244

    
245

    
246
// Test out-of-bounds access on captured objects.
247
(function testOOB() {
248
  function cons1() {
249
    this.x = 1;
250
    this.y = 2;
251
    this.z = 3;
252
  }
253
  function cons2() {
254
    this.a = 7;
255
  }
256
  function oob(constructor, branch) {
257
    var o = new constructor();
258
    if (branch) {
259
      return o.a;
260
    } else {
261
      return o.z;
262
    }
263
  }
264
  assertEquals(3, oob(cons1, false));
265
  assertEquals(3, oob(cons1, false));
266
  assertEquals(7, oob(cons2, true));
267
  assertEquals(7, oob(cons2, true));
268
  gc();  // Clears type feedback of constructor call.
269
  assertEquals(7, oob(cons2, true));
270
  assertEquals(7, oob(cons2, true));
271
  %OptimizeFunctionOnNextCall(oob);
272
  assertEquals(7, oob(cons2, true));
273
})();
274

    
275

    
276
// Test non-shallow nested graph of captured objects.
277
(function testDeep() {
278
  var deopt = { deopt:false };
279
  function constructor1() {
280
    this.x = 23;
281
  }
282
  function constructor2(nested) {
283
    this.a = 17;
284
    this.b = nested;
285
    this.c = 42;
286
  }
287
  function deep() {
288
    var o1 = new constructor1();
289
    var o2 = new constructor2(o1);
290
    assertEquals(17, o2.a);
291
    assertEquals(23, o2.b.x);
292
    assertEquals(42, o2.c);
293
    o1.x = 99;
294
    deopt.deopt;
295
    assertEquals(99, o1.x);
296
    assertEquals(99, o2.b.x);
297
  }
298
  deep(); deep();
299
  %OptimizeFunctionOnNextCall(deep);
300
  deep(); deep();
301
  delete deopt.deopt;
302
  deep(); deep();
303
})();
304

    
305

    
306
// Test materialization of a field that requires a Smi value.
307
(function testSmiField() {
308
  var deopt = { deopt:false };
309
  function constructor() {
310
    this.x = 1;
311
  }
312
  function field(x) {
313
    var o = new constructor();
314
    o.x = x;
315
    deopt.deopt
316
    assertEquals(x, o.x);
317
  }
318
  field(1); field(2);
319
  %OptimizeFunctionOnNextCall(field);
320
  field(3); field(4);
321
  delete deopt.deopt;
322
  field(5.5); field(6.5);
323
})();
324

    
325

    
326
// Test materialization of a field that requires a heap object value.
327
(function testHeapObjectField() {
328
  var deopt = { deopt:false };
329
  function constructor() {
330
    this.x = {};
331
  }
332
  function field(x) {
333
    var o = new constructor();
334
    o.x = x;
335
    deopt.deopt
336
    assertEquals(x, o.x);
337
  }
338
  field({}); field({});
339
  %OptimizeFunctionOnNextCall(field);
340
  field({}); field({});
341
  delete deopt.deopt;
342
  field(1); field(2);
343
})();