Chromium Code Reviews| 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 } | |
|
Rico
2011/09/23 07:06:52
Could we do this again with some GC's mixed in?
Lasse Reichstein
2011/09/23 09:54:39
Not necessary (discussed offline). That would only
| |
| 15349 | |
|
Rico
2011/09/23 07:06:52
Also, even though the current code just removes th
Lasse Reichstein
2011/09/23 09:54:39
Good point! Adding test for that.
| |
| 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 } | |
| OLD | NEW |