OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 15 matching lines...) Expand all Loading... |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <limits.h> | 28 #include <limits.h> |
29 | 29 |
30 #include "v8.h" | 30 #include "v8.h" |
31 | 31 |
32 #include "api.h" | 32 #include "api.h" |
33 #include "isolate.h" | 33 #include "isolate.h" |
34 #include "compilation-cache.h" | 34 #include "compilation-cache.h" |
35 #include "execution.h" | 35 #include "execution.h" |
| 36 #include "handles.h" |
36 #include "snapshot.h" | 37 #include "snapshot.h" |
37 #include "platform.h" | 38 #include "platform.h" |
38 #include "utils.h" | 39 #include "utils.h" |
39 #include "cctest.h" | 40 #include "cctest.h" |
40 #include "parser.h" | 41 #include "parser.h" |
41 #include "unicode-inl.h" | 42 #include "unicode-inl.h" |
42 | 43 |
43 static const bool kLogThreading = false; | 44 static const bool kLogThreading = false; |
44 | 45 |
45 static bool IsNaN(double x) { | 46 static bool IsNaN(double x) { |
(...skipping 15163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15209 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); | 15210 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
15210 | 15211 |
15211 // TODO(1547): Make the following also return "i". | 15212 // TODO(1547): Make the following also return "i". |
15212 // Calling with environment record as base. | 15213 // Calling with environment record as base. |
15213 TestReceiver(o, context->Global(), "func()"); | 15214 TestReceiver(o, context->Global(), "func()"); |
15214 // Calling with no base. | 15215 // Calling with no base. |
15215 TestReceiver(o, context->Global(), "(1,func)()"); | 15216 TestReceiver(o, context->Global(), "(1,func)()"); |
15216 | 15217 |
15217 foreign_context.Dispose(); | 15218 foreign_context.Dispose(); |
15218 } | 15219 } |
| 15220 |
| 15221 |
| 15222 |
| 15223 class SimpleTestResource: public String::ExternalStringResource { |
| 15224 public: |
| 15225 explicit SimpleTestResource(const uint16_t* data) : data_(data), length_(0) { |
| 15226 while (data[length_] != 0) length_++; |
| 15227 } |
| 15228 virtual ~SimpleTestResource() { } |
| 15229 virtual const uint16_t* data() const { return data_; } |
| 15230 virtual size_t length() const { return length_; } |
| 15231 private: |
| 15232 const uint16_t* data_; |
| 15233 int length_; |
| 15234 }; |
| 15235 |
| 15236 |
| 15237 THREADED_TEST(StringLock) { |
| 15238 v8::HandleScope scope; |
| 15239 LocalContext env; |
| 15240 |
| 15241 i::Isolate* isolate = i::Isolate::Current(); |
| 15242 i::Heap* heap = isolate->heap(); |
| 15243 |
| 15244 // ASCII text of test strings. |
| 15245 const char* text = "Lorem ipsum dolor sic amet."; |
| 15246 const size_t kTextLength = 27; |
| 15247 CHECK(strlen(text) == kTextLength); |
| 15248 // UC16 version of string. |
| 15249 uint16_t uc16_text[kTextLength + 1]; |
| 15250 for (unsigned i = 0; i <= kTextLength; i++) { |
| 15251 uc16_text[i] = static_cast<uint16_t>(text[i]); |
| 15252 } |
| 15253 |
| 15254 // Create some different strings and move them to old-space, |
| 15255 // so that externalization can succeede. |
| 15256 Local<String> s1 = v8_str(text); |
| 15257 Local<String> s2 = v8_str(text + 1); |
| 15258 Local<String> s3 = v8_str(text + 2); |
| 15259 heap->CollectGarbage(i::NEW_SPACE); |
| 15260 heap->CollectGarbage(i::NEW_SPACE); |
| 15261 |
| 15262 SimpleTestResource* r1 = new SimpleTestResource(uc16_text); |
| 15263 SimpleTestResource* r2 = new SimpleTestResource(uc16_text + 1); |
| 15264 SimpleTestResource* r3 = new SimpleTestResource(uc16_text + 2); |
| 15265 |
| 15266 // Check that externalization works. |
| 15267 CHECK(!s1->IsExternal()); |
| 15268 CHECK(s1->MakeExternal(r1)); |
| 15269 CHECK(s1->IsExternal()); |
| 15270 |
| 15271 // Externalize while the string is locked. |
| 15272 |
| 15273 // Use the direct interface to string locking. |
| 15274 i::Handle<i::String> s2i(v8::Utils::OpenHandle(*s2)); |
| 15275 CHECK(!heap->IsStringLocked(*s2i)); |
| 15276 LockString(s2i); // Use handle version, not Heap::LockString, to allow GC. |
| 15277 CHECK(isolate->heap()->IsStringLocked(*s2i)); |
| 15278 |
| 15279 CHECK(!s2->IsExternal()); |
| 15280 CHECK(!s2->MakeExternal(r2)); |
| 15281 CHECK(!s2->IsExternal()); |
| 15282 |
| 15283 CHECK(heap->IsStringLocked(*s2i)); |
| 15284 heap->UnlockString(*s2i); |
| 15285 CHECK(!heap->IsStringLocked(*s2i)); |
| 15286 |
| 15287 CHECK(!s2->IsExternal()); |
| 15288 CHECK(s2->MakeExternal(r2)); |
| 15289 CHECK(s2->IsExternal()); |
| 15290 |
| 15291 // Use the Handle-based scoped StringLock. |
| 15292 i::Handle<i::String> s3i(v8::Utils::OpenHandle(*s3)); |
| 15293 { |
| 15294 CHECK(!heap->IsStringLocked(*s3i)); |
| 15295 i::StringLock lock(s3i); |
| 15296 CHECK(heap->IsStringLocked(*s3i)); |
| 15297 |
| 15298 CHECK(!s3->IsExternal()); |
| 15299 CHECK(!s3->MakeExternal(r3)); |
| 15300 CHECK(!s3->IsExternal()); |
| 15301 |
| 15302 CHECK(heap->IsStringLocked(*s3i)); |
| 15303 } |
| 15304 CHECK(!heap->IsStringLocked(*s3i)); |
| 15305 |
| 15306 CHECK(!s3->IsExternal()); |
| 15307 CHECK(s3->MakeExternal(r3)); |
| 15308 CHECK(s3->IsExternal()); |
| 15309 } |
| 15310 |
| 15311 |
| 15312 THREADED_TEST(MultiStringLock) { |
| 15313 v8::HandleScope scope; |
| 15314 LocalContext env; |
| 15315 i::Isolate* isolate = i::Isolate::Current(); |
| 15316 i::Heap* heap = isolate->heap(); |
| 15317 const char* text = "Lorem ipsum dolor sic amet."; |
| 15318 |
| 15319 const int N = 16; // Must be power of 2. |
| 15320 CHECK_GT(strlen(text), static_cast<size_t>(N)); |
| 15321 |
| 15322 // Create a bunch of different strings. |
| 15323 i::Handle<i::String> strings[N]; |
| 15324 |
| 15325 for (int i = 0; i < N; i++) { |
| 15326 Local<String> s = v8_str(text + i); |
| 15327 strings[i] = v8::Utils::OpenHandle(*s); |
| 15328 } |
| 15329 |
| 15330 heap->CollectGarbage(i::NEW_SPACE); |
| 15331 heap->CollectGarbage(i::NEW_SPACE); |
| 15332 |
| 15333 // Check that start out are unlocked. |
| 15334 for (int i = 0; i < N; i++) { |
| 15335 CHECK(!heap->IsStringLocked(*strings[i])); |
| 15336 } |
| 15337 |
| 15338 // Lock them, one at a time. |
| 15339 for (int i = 0; i < N; i++) { |
| 15340 LockString(strings[i]); |
| 15341 for (int j = 0; j < N; j++) { |
| 15342 if (j <= i) { |
| 15343 CHECK(heap->IsStringLocked(*strings[j])); |
| 15344 } else { |
| 15345 CHECK(!heap->IsStringLocked(*strings[j])); |
| 15346 } |
| 15347 } |
| 15348 } |
| 15349 |
| 15350 // Unlock them in a slightly different order (not same as locking, |
| 15351 // nor the reverse order). |
| 15352 for (int i = 0; i < N; i++) { |
| 15353 int mix_i = i ^ 3; |
| 15354 heap->UnlockString(*strings[mix_i]); |
| 15355 for (int j = 0; j < N; j++) { |
| 15356 int unmix_j = j ^ 3; |
| 15357 if (unmix_j <= i) { |
| 15358 CHECK(!heap->IsStringLocked(*strings[j])); |
| 15359 } else { |
| 15360 CHECK(heap->IsStringLocked(*strings[j])); |
| 15361 } |
| 15362 } |
| 15363 } |
| 15364 } |
| 15365 |
| 15366 |
| 15367 THREADED_TEST(DuplicateStringLock) { |
| 15368 v8::HandleScope scope; |
| 15369 LocalContext env; |
| 15370 i::Isolate* isolate = i::Isolate::Current(); |
| 15371 i::Heap* heap = isolate->heap(); |
| 15372 const char* text = "Lorem ipsum dolor sic amet."; |
| 15373 |
| 15374 const int N = 16; // Must be power of 2. |
| 15375 CHECK_GT(strlen(text), static_cast<size_t>(N)); |
| 15376 |
| 15377 // Create a bunch of different strings. |
| 15378 i::Handle<i::String> strings[N]; |
| 15379 |
| 15380 for (int i = 0; i < N; i++) { |
| 15381 Local<String> s = v8_str(text + i); |
| 15382 strings[i] = v8::Utils::OpenHandle(*s); |
| 15383 } |
| 15384 |
| 15385 heap->CollectGarbage(i::NEW_SPACE); |
| 15386 heap->CollectGarbage(i::NEW_SPACE); |
| 15387 |
| 15388 // Check that strings start out unlocked. |
| 15389 for (int i = 0; i < N; i++) { |
| 15390 CHECK(!heap->IsStringLocked(*strings[i])); |
| 15391 } |
| 15392 |
| 15393 // Lock them, one at a time. |
| 15394 for (int i = 0; i < N; i++) { |
| 15395 LockString(strings[i]); |
| 15396 for (int j = 0; j < N; j++) { |
| 15397 if (j <= i) { |
| 15398 CHECK(heap->IsStringLocked(*strings[j])); |
| 15399 } else { |
| 15400 CHECK(!heap->IsStringLocked(*strings[j])); |
| 15401 } |
| 15402 } |
| 15403 } |
| 15404 |
| 15405 // Lock the first half of them a second time. |
| 15406 for (int i = 0; i < N / 2; i++) { |
| 15407 LockString(strings[i]); |
| 15408 for (int j = 0; j < N; j++) { |
| 15409 CHECK(heap->IsStringLocked(*strings[j])); |
| 15410 } |
| 15411 } |
| 15412 |
| 15413 // Unlock them in a slightly different order (not same as locking, |
| 15414 // nor the reverse order). |
| 15415 for (int i = 0; i < N; i++) { |
| 15416 int mix_i = i ^ 3; |
| 15417 heap->UnlockString(*strings[mix_i]); |
| 15418 for (int j = 0; j < N; j++) { |
| 15419 int unmix_j = j ^ 3; |
| 15420 if (unmix_j <= i && j >= N / 2) { |
| 15421 CHECK(!heap->IsStringLocked(*strings[j])); |
| 15422 } else { |
| 15423 CHECK(heap->IsStringLocked(*strings[j])); |
| 15424 } |
| 15425 } |
| 15426 } |
| 15427 |
| 15428 // Unlock the first half again. |
| 15429 for (int i = 0; i < N / 2; i++) { |
| 15430 heap->UnlockString(*strings[i]); |
| 15431 for (int j = 0; j < N; j++) { |
| 15432 if (j <= i || j >= N/ 2) { |
| 15433 CHECK(!heap->IsStringLocked(*strings[j])); |
| 15434 } else { |
| 15435 CHECK(heap->IsStringLocked(*strings[j])); |
| 15436 } |
| 15437 } |
| 15438 } |
| 15439 } |
OLD | NEW |