deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / cctest / test-weaktypedarrays.cc
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 #include <stdlib.h>
29
30 #include "src/v8.h"
31 #include "test/cctest/cctest.h"
32
33 #include "src/api.h"
34 #include "src/heap/heap.h"
35 #include "src/objects.h"
36
37 using namespace v8::internal;
38
39 static Isolate* GetIsolateFrom(LocalContext* context) {
40   return reinterpret_cast<Isolate*>((*context)->GetIsolate());
41 }
42
43
44 static int CountArrayBuffersInWeakList(Heap* heap) {
45   int count = 0;
46   for (Object* o = heap->array_buffers_list();
47        !o->IsUndefined();
48        o = JSArrayBuffer::cast(o)->weak_next()) {
49     count++;
50   }
51   return count;
52 }
53
54
55 static bool HasArrayBufferInWeakList(Heap* heap, JSArrayBuffer* ab) {
56   for (Object* o = heap->array_buffers_list();
57        !o->IsUndefined();
58        o = JSArrayBuffer::cast(o)->weak_next()) {
59     if (ab == o) return true;
60   }
61   return false;
62 }
63
64
65 static int CountViewsInNewSpaceList(Heap* heap, JSArrayBuffer* array_buffer) {
66   int count = 0;
67   for (Object* o = heap->new_array_buffer_views_list(); !o->IsUndefined();) {
68     JSArrayBufferView* view = JSArrayBufferView::cast(o);
69     if (array_buffer == view->buffer()) {
70       count++;
71     }
72     o = view->weak_next();
73   }
74   return count;
75 }
76
77
78 static int CountViews(Heap* heap, JSArrayBuffer* array_buffer) {
79   int count = 0;
80   for (Object* o = array_buffer->weak_first_view();
81        !o->IsUndefined();
82        o = JSArrayBufferView::cast(o)->weak_next()) {
83     count++;
84   }
85
86   return count + CountViewsInNewSpaceList(heap, array_buffer);
87 }
88
89
90 static bool HasViewInNewSpaceList(Heap* heap, JSArrayBufferView* ta) {
91   for (Object* o = heap->new_array_buffer_views_list(); !o->IsUndefined();
92        o = JSArrayBufferView::cast(o)->weak_next()) {
93     if (ta == o) return true;
94   }
95   return false;
96 }
97
98
99 static bool HasViewInWeakList(Heap* heap, JSArrayBuffer* array_buffer,
100                               JSArrayBufferView* ta) {
101   for (Object* o = array_buffer->weak_first_view();
102        !o->IsUndefined();
103        o = JSArrayBufferView::cast(o)->weak_next()) {
104     if (ta == o) return true;
105   }
106   return HasViewInNewSpaceList(heap, ta);
107 }
108
109
110 TEST(WeakArrayBuffersFromApi) {
111   v8::V8::Initialize();
112   LocalContext context;
113   Isolate* isolate = GetIsolateFrom(&context);
114
115   int start = CountArrayBuffersInWeakList(isolate->heap());
116   {
117     v8::HandleScope s1(context->GetIsolate());
118     v8::Handle<v8::ArrayBuffer> ab1 =
119         v8::ArrayBuffer::New(context->GetIsolate(), 256);
120     {
121       v8::HandleScope s2(context->GetIsolate());
122       v8::Handle<v8::ArrayBuffer> ab2 =
123           v8::ArrayBuffer::New(context->GetIsolate(), 128);
124
125       Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1);
126       Handle<JSArrayBuffer> iab2 = v8::Utils::OpenHandle(*ab2);
127       CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()) - start);
128       CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab1));
129       CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab2));
130     }
131     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
132     CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
133     {
134       HandleScope scope2(isolate);
135       Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1);
136
137       CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab1));
138     }
139   }
140
141   isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
142   CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap()));
143 }
144
145
146 TEST(WeakArrayBuffersFromScript) {
147   v8::V8::Initialize();
148   LocalContext context;
149   Isolate* isolate = GetIsolateFrom(&context);
150   int start = CountArrayBuffersInWeakList(isolate->heap());
151
152   for (int i = 1; i <= 3; i++) {
153     // Create 3 array buffers, make i-th of them garbage,
154     // validate correct state of array buffer weak list.
155     CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap()));
156     {
157       v8::HandleScope scope(context->GetIsolate());
158
159       {
160         v8::HandleScope s1(context->GetIsolate());
161         CompileRun("var ab1 = new ArrayBuffer(256);"
162                    "var ab2 = new ArrayBuffer(256);"
163                    "var ab3 = new ArrayBuffer(256);");
164         v8::Handle<v8::ArrayBuffer> ab1 =
165             v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab1"));
166         v8::Handle<v8::ArrayBuffer> ab2 =
167             v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab2"));
168         v8::Handle<v8::ArrayBuffer> ab3 =
169             v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab3"));
170
171         CHECK_EQ(3, CountArrayBuffersInWeakList(isolate->heap()) - start);
172         CHECK(HasArrayBufferInWeakList(isolate->heap(),
173               *v8::Utils::OpenHandle(*ab1)));
174         CHECK(HasArrayBufferInWeakList(isolate->heap(),
175               *v8::Utils::OpenHandle(*ab2)));
176         CHECK(HasArrayBufferInWeakList(isolate->heap(),
177               *v8::Utils::OpenHandle(*ab3)));
178       }
179
180       i::ScopedVector<char> source(1024);
181       i::SNPrintF(source, "ab%d = null;", i);
182       CompileRun(source.start());
183       isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
184
185       CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()) - start);
186
187       {
188         v8::HandleScope s2(context->GetIsolate());
189         for (int j = 1; j <= 3; j++) {
190           if (j == i) continue;
191           i::SNPrintF(source, "ab%d", j);
192           v8::Handle<v8::ArrayBuffer> ab =
193               v8::Handle<v8::ArrayBuffer>::Cast(CompileRun(source.start()));
194           CHECK(HasArrayBufferInWeakList(isolate->heap(),
195                 *v8::Utils::OpenHandle(*ab)));
196           }
197       }
198
199       CompileRun("ab1 = null; ab2 = null; ab3 = null;");
200     }
201
202     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
203     CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap()));
204   }
205 }
206
207 template <typename View>
208 void TestViewFromApi() {
209   v8::V8::Initialize();
210   LocalContext context;
211   Isolate* isolate = GetIsolateFrom(&context);
212
213   v8::HandleScope s1(context->GetIsolate());
214   v8::Handle<v8::ArrayBuffer> ab =
215       v8::ArrayBuffer::New(context->GetIsolate(), 2048);
216   Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab);
217   {
218     v8::HandleScope s2(context->GetIsolate());
219     v8::Handle<View> ta1 = View::New(ab, 0, 256);
220     {
221       v8::HandleScope s3(context->GetIsolate());
222       v8::Handle<View> ta2 = View::New(ab, 0, 128);
223
224       Handle<JSArrayBufferView> ita1 = v8::Utils::OpenHandle(*ta1);
225       Handle<JSArrayBufferView> ita2 = v8::Utils::OpenHandle(*ta2);
226       CHECK_EQ(2, CountViews(isolate->heap(), *iab));
227       CHECK(HasViewInWeakList(isolate->heap(), *iab, *ita1));
228       CHECK(HasViewInWeakList(isolate->heap(), *iab, *ita2));
229     }
230     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
231     CHECK_EQ(1, CountViews(isolate->heap(), *iab));
232     Handle<JSArrayBufferView> ita1 = v8::Utils::OpenHandle(*ta1);
233     CHECK(HasViewInWeakList(isolate->heap(), *iab, *ita1));
234   }
235   isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
236
237   CHECK_EQ(0, CountViews(isolate->heap(), *iab));
238 }
239
240
241 TEST(Uint8ArrayFromApi) {
242   TestViewFromApi<v8::Uint8Array>();
243 }
244
245
246 TEST(Int8ArrayFromApi) {
247   TestViewFromApi<v8::Int8Array>();
248 }
249
250
251 TEST(Uint16ArrayFromApi) {
252   TestViewFromApi<v8::Uint16Array>();
253 }
254
255
256 TEST(Int16ArrayFromApi) {
257   TestViewFromApi<v8::Int16Array>();
258 }
259
260
261 TEST(Uint32ArrayFromApi) {
262   TestViewFromApi<v8::Uint32Array>();
263 }
264
265
266 TEST(Int32ArrayFromApi) {
267   TestViewFromApi<v8::Int32Array>();
268 }
269
270
271 TEST(Float32ArrayFromApi) {
272   TestViewFromApi<v8::Float32Array>();
273 }
274
275
276 TEST(Float64ArrayFromApi) {
277   TestViewFromApi<v8::Float64Array>();
278 }
279
280
281 TEST(Uint8ClampedArrayFromApi) {
282   TestViewFromApi<v8::Uint8ClampedArray>();
283 }
284
285
286 TEST(DataViewFromApi) {
287   TestViewFromApi<v8::DataView>();
288 }
289
290 template <typename TypedArray>
291 static void TestTypedArrayFromScript(const char* constructor) {
292   v8::V8::Initialize();
293   LocalContext context;
294   Isolate* isolate = GetIsolateFrom(&context);
295   v8::HandleScope scope(context->GetIsolate());
296   int start = CountArrayBuffersInWeakList(isolate->heap());
297   CompileRun("var ab = new ArrayBuffer(2048);");
298   for (int i = 1; i <= 3; i++) {
299     // Create 3 typed arrays, make i-th of them garbage,
300     // validate correct state of typed array weak list.
301     v8::HandleScope s0(context->GetIsolate());
302     i::ScopedVector<char> source(2048);
303
304     CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
305
306     {
307       v8::HandleScope s1(context->GetIsolate());
308       i::SNPrintF(source,
309               "var ta1 = new %s(ab);"
310               "var ta2 = new %s(ab);"
311               "var ta3 = new %s(ab)",
312               constructor, constructor, constructor);
313
314       CompileRun(source.start());
315       v8::Handle<v8::ArrayBuffer> ab =
316           v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab"));
317       v8::Handle<TypedArray> ta1 =
318           v8::Handle<TypedArray>::Cast(CompileRun("ta1"));
319       v8::Handle<TypedArray> ta2 =
320           v8::Handle<TypedArray>::Cast(CompileRun("ta2"));
321       v8::Handle<TypedArray> ta3 =
322           v8::Handle<TypedArray>::Cast(CompileRun("ta3"));
323       CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
324       Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab);
325       CHECK_EQ(3, CountViews(isolate->heap(), *iab));
326       CHECK(HasViewInWeakList(isolate->heap(), *iab,
327                               *v8::Utils::OpenHandle(*ta1)));
328       CHECK(HasViewInWeakList(isolate->heap(), *iab,
329                               *v8::Utils::OpenHandle(*ta2)));
330       CHECK(HasViewInWeakList(isolate->heap(), *iab,
331                               *v8::Utils::OpenHandle(*ta3)));
332     }
333
334     i::SNPrintF(source, "ta%d = null;", i);
335     CompileRun(source.start());
336     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
337
338     CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
339
340     {
341       v8::HandleScope s2(context->GetIsolate());
342       v8::Handle<v8::ArrayBuffer> ab =
343           v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab"));
344       Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab);
345       CHECK_EQ(2, CountViews(isolate->heap(), *iab));
346       for (int j = 1; j <= 3; j++) {
347         if (j == i) continue;
348         i::SNPrintF(source, "ta%d", j);
349         v8::Handle<TypedArray> ta =
350             v8::Handle<TypedArray>::Cast(CompileRun(source.start()));
351         CHECK(HasViewInWeakList(isolate->heap(), *iab,
352                                 *v8::Utils::OpenHandle(*ta)));
353       }
354     }
355
356     CompileRun("ta1 = null; ta2 = null; ta3 = null;");
357     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
358
359     CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
360
361     {
362       v8::HandleScope s3(context->GetIsolate());
363       v8::Handle<v8::ArrayBuffer> ab =
364           v8::Handle<v8::ArrayBuffer>::Cast(CompileRun("ab"));
365       Handle<JSArrayBuffer> iab = v8::Utils::OpenHandle(*ab);
366       CHECK_EQ(0, CountViews(isolate->heap(), *iab));
367     }
368   }
369 }
370
371
372 TEST(Uint8ArrayFromScript) {
373   TestTypedArrayFromScript<v8::Uint8Array>("Uint8Array");
374 }
375
376
377 TEST(Int8ArrayFromScript) {
378   TestTypedArrayFromScript<v8::Int8Array>("Int8Array");
379 }
380
381
382 TEST(Uint16ArrayFromScript) {
383   TestTypedArrayFromScript<v8::Uint16Array>("Uint16Array");
384 }
385
386
387 TEST(Int16ArrayFromScript) {
388   TestTypedArrayFromScript<v8::Int16Array>("Int16Array");
389 }
390
391
392 TEST(Uint32ArrayFromScript) {
393   TestTypedArrayFromScript<v8::Uint32Array>("Uint32Array");
394 }
395
396
397 TEST(Int32ArrayFromScript) {
398   TestTypedArrayFromScript<v8::Int32Array>("Int32Array");
399 }
400
401
402 TEST(Float32ArrayFromScript) {
403   TestTypedArrayFromScript<v8::Float32Array>("Float32Array");
404 }
405
406
407 TEST(Float64ArrayFromScript) {
408   TestTypedArrayFromScript<v8::Float64Array>("Float64Array");
409 }
410
411
412 TEST(Uint8ClampedArrayFromScript) {
413   TestTypedArrayFromScript<v8::Uint8ClampedArray>("Uint8ClampedArray");
414 }
415
416
417 TEST(DataViewFromScript) {
418   TestTypedArrayFromScript<v8::DataView>("DataView");
419 }