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" | |
37 #include "snapshot.h" | 36 #include "snapshot.h" |
38 #include "platform.h" | 37 #include "platform.h" |
39 #include "utils.h" | 38 #include "utils.h" |
40 #include "cctest.h" | 39 #include "cctest.h" |
41 #include "parser.h" | 40 #include "parser.h" |
42 #include "unicode-inl.h" | 41 #include "unicode-inl.h" |
43 | 42 |
44 static const bool kLogThreading = false; | 43 static const bool kLogThreading = false; |
45 | 44 |
46 static bool IsNaN(double x) { | 45 static bool IsNaN(double x) { |
(...skipping 15387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15434 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); | 15433 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
15435 | 15434 |
15436 // TODO(1547): Make the following also return "i". | 15435 // TODO(1547): Make the following also return "i". |
15437 // Calling with environment record as base. | 15436 // Calling with environment record as base. |
15438 TestReceiver(o, context->Global(), "func()"); | 15437 TestReceiver(o, context->Global(), "func()"); |
15439 // Calling with no base. | 15438 // Calling with no base. |
15440 TestReceiver(o, context->Global(), "(1,func)()"); | 15439 TestReceiver(o, context->Global(), "(1,func)()"); |
15441 | 15440 |
15442 foreign_context.Dispose(); | 15441 foreign_context.Dispose(); |
15443 } | 15442 } |
15444 | |
15445 | |
15446 | |
15447 class SimpleTestResource: public String::ExternalStringResource { | |
15448 public: | |
15449 explicit SimpleTestResource(const uint16_t* data) : data_(data), length_(0) { | |
15450 while (data[length_] != 0) length_++; | |
15451 } | |
15452 virtual ~SimpleTestResource() { } | |
15453 virtual const uint16_t* data() const { return data_; } | |
15454 virtual size_t length() const { return length_; } | |
15455 private: | |
15456 const uint16_t* data_; | |
15457 int length_; | |
15458 }; | |
15459 | |
15460 | |
15461 THREADED_TEST(StringLock) { | |
15462 v8::HandleScope scope; | |
15463 LocalContext env; | |
15464 | |
15465 i::Isolate* isolate = i::Isolate::Current(); | |
15466 i::Heap* heap = isolate->heap(); | |
15467 | |
15468 // ASCII text of test strings. | |
15469 const char* text = "Lorem ipsum dolor sic amet."; | |
15470 const size_t kTextLength = 27; | |
15471 CHECK(strlen(text) == kTextLength); | |
15472 // UC16 version of string. | |
15473 uint16_t uc16_text[kTextLength + 1]; | |
15474 for (unsigned i = 0; i <= kTextLength; i++) { | |
15475 uc16_text[i] = static_cast<uint16_t>(text[i]); | |
15476 } | |
15477 | |
15478 // Create some different strings and move them to old-space, | |
15479 // so that externalization can succeede. | |
15480 Local<String> s1 = v8_str(text); | |
15481 Local<String> s2 = v8_str(text + 1); | |
15482 Local<String> s3 = v8_str(text + 2); | |
15483 heap->CollectGarbage(i::NEW_SPACE); | |
15484 heap->CollectGarbage(i::NEW_SPACE); | |
15485 | |
15486 SimpleTestResource* r1 = new SimpleTestResource(uc16_text); | |
15487 SimpleTestResource* r2 = new SimpleTestResource(uc16_text + 1); | |
15488 SimpleTestResource* r3 = new SimpleTestResource(uc16_text + 2); | |
15489 | |
15490 // Check that externalization works. | |
15491 CHECK(!s1->IsExternal()); | |
15492 CHECK(s1->MakeExternal(r1)); | |
15493 CHECK(s1->IsExternal()); | |
15494 | |
15495 // Externalize while the string is locked. | |
15496 | |
15497 // Use the direct interface to string locking. | |
15498 i::Handle<i::String> s2i(v8::Utils::OpenHandle(*s2)); | |
15499 CHECK(!heap->IsStringLocked(*s2i)); | |
15500 LockString(s2i); // Use handle version, not Heap::LockString, to allow GC. | |
15501 CHECK(isolate->heap()->IsStringLocked(*s2i)); | |
15502 | |
15503 CHECK(!s2->IsExternal()); | |
15504 CHECK(!s2->MakeExternal(r2)); | |
15505 CHECK(!s2->IsExternal()); | |
15506 | |
15507 CHECK(heap->IsStringLocked(*s2i)); | |
15508 heap->UnlockString(*s2i); | |
15509 CHECK(!heap->IsStringLocked(*s2i)); | |
15510 | |
15511 CHECK(!s2->IsExternal()); | |
15512 CHECK(s2->MakeExternal(r2)); | |
15513 CHECK(s2->IsExternal()); | |
15514 | |
15515 // Use the Handle-based scoped StringLock. | |
15516 i::Handle<i::String> s3i(v8::Utils::OpenHandle(*s3)); | |
15517 { | |
15518 CHECK(!heap->IsStringLocked(*s3i)); | |
15519 i::StringLock lock(s3i); | |
15520 CHECK(heap->IsStringLocked(*s3i)); | |
15521 | |
15522 CHECK(!s3->IsExternal()); | |
15523 CHECK(!s3->MakeExternal(r3)); | |
15524 CHECK(!s3->IsExternal()); | |
15525 | |
15526 CHECK(heap->IsStringLocked(*s3i)); | |
15527 } | |
15528 CHECK(!heap->IsStringLocked(*s3i)); | |
15529 | |
15530 CHECK(!s3->IsExternal()); | |
15531 CHECK(s3->MakeExternal(r3)); | |
15532 CHECK(s3->IsExternal()); | |
15533 } | |
15534 | |
15535 | |
15536 THREADED_TEST(MultiStringLock) { | |
15537 v8::HandleScope scope; | |
15538 LocalContext env; | |
15539 i::Isolate* isolate = i::Isolate::Current(); | |
15540 i::Heap* heap = isolate->heap(); | |
15541 const char* text = "Lorem ipsum dolor sic amet."; | |
15542 | |
15543 const int N = 16; // Must be power of 2. | |
15544 CHECK_GT(strlen(text), static_cast<size_t>(N)); | |
15545 | |
15546 // Create a bunch of different strings. | |
15547 i::Handle<i::String> strings[N]; | |
15548 | |
15549 for (int i = 0; i < N; i++) { | |
15550 Local<String> s = v8_str(text + i); | |
15551 strings[i] = v8::Utils::OpenHandle(*s); | |
15552 } | |
15553 | |
15554 heap->CollectGarbage(i::NEW_SPACE); | |
15555 heap->CollectGarbage(i::NEW_SPACE); | |
15556 | |
15557 // Check that start out are unlocked. | |
15558 for (int i = 0; i < N; i++) { | |
15559 CHECK(!heap->IsStringLocked(*strings[i])); | |
15560 } | |
15561 | |
15562 // Lock them, one at a time. | |
15563 for (int i = 0; i < N; i++) { | |
15564 LockString(strings[i]); | |
15565 for (int j = 0; j < N; j++) { | |
15566 if (j <= i) { | |
15567 CHECK(heap->IsStringLocked(*strings[j])); | |
15568 } else { | |
15569 CHECK(!heap->IsStringLocked(*strings[j])); | |
15570 } | |
15571 } | |
15572 } | |
15573 | |
15574 // Unlock them in a slightly different order (not same as locking, | |
15575 // nor the reverse order). | |
15576 for (int i = 0; i < N; i++) { | |
15577 int mix_i = i ^ 3; | |
15578 heap->UnlockString(*strings[mix_i]); | |
15579 for (int j = 0; j < N; j++) { | |
15580 int unmix_j = j ^ 3; | |
15581 if (unmix_j <= i) { | |
15582 CHECK(!heap->IsStringLocked(*strings[j])); | |
15583 } else { | |
15584 CHECK(heap->IsStringLocked(*strings[j])); | |
15585 } | |
15586 } | |
15587 } | |
15588 } | |
15589 | |
15590 | |
15591 THREADED_TEST(DuplicateStringLock) { | |
15592 v8::HandleScope scope; | |
15593 LocalContext env; | |
15594 i::Isolate* isolate = i::Isolate::Current(); | |
15595 i::Heap* heap = isolate->heap(); | |
15596 const char* text = "Lorem ipsum dolor sic amet."; | |
15597 | |
15598 const int N = 16; // Must be power of 2. | |
15599 CHECK_GT(strlen(text), static_cast<size_t>(N)); | |
15600 | |
15601 // Create a bunch of different strings. | |
15602 i::Handle<i::String> strings[N]; | |
15603 | |
15604 for (int i = 0; i < N; i++) { | |
15605 Local<String> s = v8_str(text + i); | |
15606 strings[i] = v8::Utils::OpenHandle(*s); | |
15607 } | |
15608 | |
15609 heap->CollectGarbage(i::NEW_SPACE); | |
15610 heap->CollectGarbage(i::NEW_SPACE); | |
15611 | |
15612 // Check that strings start out unlocked. | |
15613 for (int i = 0; i < N; i++) { | |
15614 CHECK(!heap->IsStringLocked(*strings[i])); | |
15615 } | |
15616 | |
15617 // Lock them, one at a time. | |
15618 for (int i = 0; i < N; i++) { | |
15619 LockString(strings[i]); | |
15620 for (int j = 0; j < N; j++) { | |
15621 if (j <= i) { | |
15622 CHECK(heap->IsStringLocked(*strings[j])); | |
15623 } else { | |
15624 CHECK(!heap->IsStringLocked(*strings[j])); | |
15625 } | |
15626 } | |
15627 } | |
15628 | |
15629 // Lock the first half of them a second time. | |
15630 for (int i = 0; i < N / 2; i++) { | |
15631 LockString(strings[i]); | |
15632 for (int j = 0; j < N; j++) { | |
15633 CHECK(heap->IsStringLocked(*strings[j])); | |
15634 } | |
15635 } | |
15636 | |
15637 // Unlock them in a slightly different order (not same as locking, | |
15638 // nor the reverse order). | |
15639 for (int i = 0; i < N; i++) { | |
15640 int mix_i = i ^ 3; | |
15641 heap->UnlockString(*strings[mix_i]); | |
15642 for (int j = 0; j < N; j++) { | |
15643 int unmix_j = j ^ 3; | |
15644 if (unmix_j <= i && j >= N / 2) { | |
15645 CHECK(!heap->IsStringLocked(*strings[j])); | |
15646 } else { | |
15647 CHECK(heap->IsStringLocked(*strings[j])); | |
15648 } | |
15649 } | |
15650 } | |
15651 | |
15652 // Unlock the first half again. | |
15653 for (int i = 0; i < N / 2; i++) { | |
15654 heap->UnlockString(*strings[i]); | |
15655 for (int j = 0; j < N; j++) { | |
15656 if (j <= i || j >= N/ 2) { | |
15657 CHECK(!heap->IsStringLocked(*strings[j])); | |
15658 } else { | |
15659 CHECK(heap->IsStringLocked(*strings[j])); | |
15660 } | |
15661 } | |
15662 } | |
15663 } | |
OLD | NEW |