OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 static bool HasArrayBufferInWeakList(Heap* heap, JSArrayBuffer* ab) { | 55 static bool HasArrayBufferInWeakList(Heap* heap, JSArrayBuffer* ab) { |
56 for (Object* o = heap->array_buffers_list(); | 56 for (Object* o = heap->array_buffers_list(); |
57 !o->IsUndefined(); | 57 !o->IsUndefined(); |
58 o = JSArrayBuffer::cast(o)->weak_next()) { | 58 o = JSArrayBuffer::cast(o)->weak_next()) { |
59 if (ab == o) return true; | 59 if (ab == o) return true; |
60 } | 60 } |
61 return false; | 61 return false; |
62 } | 62 } |
63 | 63 |
64 | 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) { | 65 TEST(WeakArrayBuffersFromScript) { |
147 v8::V8::Initialize(); | 66 v8::V8::Initialize(); |
148 LocalContext context; | 67 LocalContext context; |
149 Isolate* isolate = GetIsolateFrom(&context); | 68 Isolate* isolate = GetIsolateFrom(&context); |
150 int start = CountArrayBuffersInWeakList(isolate->heap()); | 69 int start = CountArrayBuffersInWeakList(isolate->heap()); |
151 | 70 |
152 for (int i = 1; i <= 3; i++) { | 71 for (int i = 1; i <= 3; i++) { |
153 // Create 3 array buffers, make i-th of them garbage, | 72 // Create 3 array buffers, make i-th of them garbage, |
154 // validate correct state of array buffer weak list. | 73 // validate correct state of array buffer weak list. |
155 CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); | 74 CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 } | 115 } |
197 } | 116 } |
198 | 117 |
199 CompileRun("ab1 = null; ab2 = null; ab3 = null;"); | 118 CompileRun("ab1 = null; ab2 = null; ab3 = null;"); |
200 } | 119 } |
201 | 120 |
202 isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 121 isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
203 CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); | 122 CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap())); |
204 } | 123 } |
205 } | 124 } |
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 } | |
OLD | NEW |