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 strings 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(uc16_text); | |
15263 SimpleTestResource r2(uc16_text + 1); | |
15264 SimpleTestResource r3(uc16_text + 2); | |
15265 | |
15266 // Check that externalization works. | |
15267 CHECK(!s1->IsExternal()); | |
15268 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 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 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 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 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 start out are 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 more. | |
Rico
2011/09/26 07:25:30
remove more from comment?
| |
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 |