Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Unified Diff: test/cctest/test-api.cc

Issue 7977001: Added ability to lock strings to prevent their representation or encoding from changing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix bug in test when running threaded. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 4d5df48d41fd5e1d0973d692426101dea4f8c204..23ceee2411a3ecc97ec3c89c903861802a1ce0cd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -33,6 +33,7 @@
#include "isolate.h"
#include "compilation-cache.h"
#include "execution.h"
+#include "handles.h"
#include "snapshot.h"
#include "platform.h"
#include "utils.h"
@@ -15216,3 +15217,223 @@ THREADED_TEST(ForeignFunctionReceiver) {
foreign_context.Dispose();
}
+
+
+
+class SimpleTestResource: public String::ExternalStringResource {
+ public:
+ explicit SimpleTestResource(const uint16_t* data) : data_(data), length_(0) {
+ while (data[length_] != 0) length_++;
+ }
+ virtual ~SimpleTestResource() { }
+ virtual const uint16_t* data() const { return data_; }
+ virtual size_t length() const { return length_; }
+ private:
+ const uint16_t* data_;
+ int length_;
+};
+
+
+THREADED_TEST(StringLock) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ i::Isolate* isolate = i::Isolate::Current();
+ i::Heap* heap = isolate->heap();
+
+ // ASCII text of test strings.
+ const char* text = "Lorem ipsum dolor sic amet.";
+ const size_t kTextLength = 27;
+ CHECK(strlen(text) == kTextLength);
+ // UC16 version of string.
+ uint16_t uc16_text[kTextLength + 1];
+ for (unsigned i = 0; i <= kTextLength; i++) {
+ uc16_text[i] = static_cast<uint16_t>(text[i]);
+ }
+
+ // Create some different strings and move them to old-space,
+ // so that externalization can succeede.
+ Local<String> s1 = v8_str(text);
+ Local<String> s2 = v8_str(text + 1);
+ Local<String> s3 = v8_str(text + 2);
+ heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectGarbage(i::NEW_SPACE);
+
+ SimpleTestResource* r1 = new SimpleTestResource(uc16_text);
+ SimpleTestResource* r2 = new SimpleTestResource(uc16_text + 1);
+ SimpleTestResource* r3 = new SimpleTestResource(uc16_text + 2);
+
+ // Check that externalization works.
+ CHECK(!s1->IsExternal());
+ CHECK(s1->MakeExternal(r1));
+ CHECK(s1->IsExternal());
+
+ // Externalize while the string is locked.
+
+ // Use the direct interface to string locking.
+ i::Handle<i::String> s2i(v8::Utils::OpenHandle(*s2));
+ CHECK(!heap->IsStringLocked(*s2i));
+ LockString(s2i); // Use handle version, not Heap::LockString, to allow GC.
+ CHECK(isolate->heap()->IsStringLocked(*s2i));
+
+ CHECK(!s2->IsExternal());
+ CHECK(!s2->MakeExternal(r2));
+ CHECK(!s2->IsExternal());
+
+ CHECK(heap->IsStringLocked(*s2i));
+ heap->UnlockString(*s2i);
+ CHECK(!heap->IsStringLocked(*s2i));
+
+ CHECK(!s2->IsExternal());
+ CHECK(s2->MakeExternal(r2));
+ CHECK(s2->IsExternal());
+
+ // Use the Handle-based scoped StringLock.
+ i::Handle<i::String> s3i(v8::Utils::OpenHandle(*s3));
+ {
+ CHECK(!heap->IsStringLocked(*s3i));
+ i::StringLock lock(s3i);
+ CHECK(heap->IsStringLocked(*s3i));
+
+ CHECK(!s3->IsExternal());
+ CHECK(!s3->MakeExternal(r3));
+ CHECK(!s3->IsExternal());
+
+ CHECK(heap->IsStringLocked(*s3i));
+ }
+ CHECK(!heap->IsStringLocked(*s3i));
+
+ CHECK(!s3->IsExternal());
+ CHECK(s3->MakeExternal(r3));
+ CHECK(s3->IsExternal());
+}
+
+
+THREADED_TEST(MultiStringLock) {
+ v8::HandleScope scope;
+ LocalContext env;
+ i::Isolate* isolate = i::Isolate::Current();
+ i::Heap* heap = isolate->heap();
+ const char* text = "Lorem ipsum dolor sic amet.";
+
+ const int N = 16; // Must be power of 2.
+ CHECK_GT(strlen(text), static_cast<size_t>(N));
+
+ // Create a bunch of different strings.
+ i::Handle<i::String> strings[N];
+
+ for (int i = 0; i < N; i++) {
+ Local<String> s = v8_str(text + i);
+ strings[i] = v8::Utils::OpenHandle(*s);
+ }
+
+ heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectGarbage(i::NEW_SPACE);
+
+ // Check that start out are unlocked.
+ for (int i = 0; i < N; i++) {
+ CHECK(!heap->IsStringLocked(*strings[i]));
+ }
+
+ // Lock them, one at a time.
+ for (int i = 0; i < N; i++) {
+ LockString(strings[i]);
+ for (int j = 0; j < N; j++) {
+ if (j <= i) {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ } else {
+ CHECK(!heap->IsStringLocked(*strings[j]));
+ }
+ }
+ }
+
+ // Unlock them in a slightly different order (not same as locking,
+ // nor the reverse order).
+ for (int i = 0; i < N; i++) {
+ int mix_i = i ^ 3;
+ heap->UnlockString(*strings[mix_i]);
+ for (int j = 0; j < N; j++) {
+ int unmix_j = j ^ 3;
+ if (unmix_j <= i) {
+ CHECK(!heap->IsStringLocked(*strings[j]));
+ } else {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ }
+ }
+ }
+}
+
+
+THREADED_TEST(DuplicateStringLock) {
+ v8::HandleScope scope;
+ LocalContext env;
+ i::Isolate* isolate = i::Isolate::Current();
+ i::Heap* heap = isolate->heap();
+ const char* text = "Lorem ipsum dolor sic amet.";
+
+ const int N = 16; // Must be power of 2.
+ CHECK_GT(strlen(text), static_cast<size_t>(N));
+
+ // Create a bunch of different strings.
+ i::Handle<i::String> strings[N];
+
+ for (int i = 0; i < N; i++) {
+ Local<String> s = v8_str(text + i);
+ strings[i] = v8::Utils::OpenHandle(*s);
+ }
+
+ heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectGarbage(i::NEW_SPACE);
+
+ // Check that strings start out unlocked.
+ for (int i = 0; i < N; i++) {
+ CHECK(!heap->IsStringLocked(*strings[i]));
+ }
+
+ // Lock them, one at a time.
+ for (int i = 0; i < N; i++) {
+ LockString(strings[i]);
+ for (int j = 0; j < N; j++) {
+ if (j <= i) {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ } else {
+ CHECK(!heap->IsStringLocked(*strings[j]));
+ }
+ }
+ }
+
+ // Lock the first half of them a second time.
+ for (int i = 0; i < N / 2; i++) {
+ LockString(strings[i]);
+ for (int j = 0; j < N; j++) {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ }
+ }
+
+ // Unlock them in a slightly different order (not same as locking,
+ // nor the reverse order).
+ for (int i = 0; i < N; i++) {
+ int mix_i = i ^ 3;
+ heap->UnlockString(*strings[mix_i]);
+ for (int j = 0; j < N; j++) {
+ int unmix_j = j ^ 3;
+ if (unmix_j <= i && j >= N / 2) {
+ CHECK(!heap->IsStringLocked(*strings[j]));
+ } else {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ }
+ }
+ }
+
+ // Unlock the first half again.
+ for (int i = 0; i < N / 2; i++) {
+ heap->UnlockString(*strings[i]);
+ for (int j = 0; j < N; j++) {
+ if (j <= i || j >= N/ 2) {
+ CHECK(!heap->IsStringLocked(*strings[j]));
+ } else {
+ CHECK(heap->IsStringLocked(*strings[j]));
+ }
+ }
+ }
+}
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698