OLD | NEW |
---|---|
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 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 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 }; | 413 }; |
414 | 414 |
415 | 415 |
416 int TestResource::dispose_count = 0; | 416 int TestResource::dispose_count = 0; |
417 | 417 |
418 | 418 |
419 class TestAsciiResource: public String::ExternalAsciiStringResource { | 419 class TestAsciiResource: public String::ExternalAsciiStringResource { |
420 public: | 420 public: |
421 static int dispose_count; | 421 static int dispose_count; |
422 | 422 |
423 explicit TestAsciiResource(char* data) | 423 explicit TestAsciiResource(const char* data) |
424 : data_(data), | 424 : data_(data), |
425 length_(strlen(data)) { } | 425 length_(strlen(data)) { } |
426 | 426 |
427 ~TestAsciiResource() { | 427 ~TestAsciiResource() { |
428 i::DeleteArray(data_); | 428 i::DeleteArray(data_); |
429 ++dispose_count; | 429 ++dispose_count; |
430 } | 430 } |
431 | 431 |
432 const char* data() const { | 432 const char* data() const { |
433 return data_; | 433 return data_; |
434 } | 434 } |
435 | 435 |
436 size_t length() const { | 436 size_t length() const { |
437 return length_; | 437 return length_; |
438 } | 438 } |
439 private: | 439 private: |
440 char* data_; | 440 const char* data_; |
441 size_t length_; | 441 size_t length_; |
442 }; | 442 }; |
443 | 443 |
444 | 444 |
445 int TestAsciiResource::dispose_count = 0; | 445 int TestAsciiResource::dispose_count = 0; |
446 | 446 |
447 | 447 |
448 THREADED_TEST(ScriptUsingStringResource) { | 448 THREADED_TEST(ScriptUsingStringResource) { |
449 TestResource::dispose_count = 0; | 449 TestResource::dispose_count = 0; |
450 const char* c_source = "1 + 2 * 3"; | 450 const char* c_source = "1 + 2 * 3"; |
(...skipping 5695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6146 CHECK_EQ(v8::Integer::New(123), clone->Get(v8_str("beta"))); | 6146 CHECK_EQ(v8::Integer::New(123), clone->Get(v8_str("beta"))); |
6147 CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma"))); | 6147 CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma"))); |
6148 | 6148 |
6149 // Set a property on the clone, verify each object. | 6149 // Set a property on the clone, verify each object. |
6150 clone->Set(v8_str("beta"), v8::Integer::New(456)); | 6150 clone->Set(v8_str("beta"), v8::Integer::New(456)); |
6151 CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta"))); | 6151 CHECK_EQ(v8::Integer::New(123), obj->Get(v8_str("beta"))); |
6152 CHECK_EQ(v8::Integer::New(456), clone->Get(v8_str("beta"))); | 6152 CHECK_EQ(v8::Integer::New(456), clone->Get(v8_str("beta"))); |
6153 } | 6153 } |
6154 | 6154 |
6155 | 6155 |
6156 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | |
6157 public: | |
6158 explicit AsciiVectorResource(i::Vector<const char> vector) | |
6159 : data_(vector) {} | |
6160 virtual ~AsciiVectorResource() {} | |
6161 virtual size_t length() const { return data_.length(); } | |
6162 virtual const char* data() const { return data_.start(); } | |
6163 private: | |
6164 i::Vector<const char> data_; | |
6165 }; | |
6166 | |
6167 | |
6168 class UC16VectorResource : public v8::String::ExternalStringResource { | |
6169 public: | |
6170 explicit UC16VectorResource(i::Vector<const i::uc16> vector) | |
6171 : data_(vector) {} | |
6172 virtual ~UC16VectorResource() {} | |
6173 virtual size_t length() const { return data_.length(); } | |
6174 virtual const i::uc16* data() const { return data_.start(); } | |
6175 private: | |
6176 i::Vector<const i::uc16> data_; | |
6177 }; | |
6178 | |
6179 | |
6180 static void MorphAString(i::String* string, | |
6181 AsciiVectorResource* ascii_resource, | |
6182 UC16VectorResource* uc16_resource) { | |
6183 CHECK(i::StringShape(string).IsExternal()); | |
6184 if (string->IsAsciiRepresentation()) { | |
6185 // Check old map is not symbol or long. | |
6186 CHECK(string->map() == i::Heap::short_external_ascii_string_map() || | |
6187 string->map() == i::Heap::medium_external_ascii_string_map()); | |
6188 // Morph external string to be TwoByte string. | |
6189 if (string->length() <= i::String::kMaxShortStringSize) { | |
6190 string->set_map(i::Heap::short_external_string_map()); | |
6191 } else { | |
6192 string->set_map(i::Heap::medium_external_string_map()); | |
6193 } | |
6194 i::ExternalTwoByteString* morphed = | |
6195 i::ExternalTwoByteString::cast(string); | |
6196 morphed->set_resource(uc16_resource); | |
6197 } else { | |
6198 // Check old map is not symbol or long. | |
6199 CHECK(string->map() == i::Heap::short_external_string_map() || | |
6200 string->map() == i::Heap::medium_external_string_map()); | |
6201 // Morph external string to be ASCII string. | |
6202 if (string->length() <= i::String::kMaxShortStringSize) { | |
6203 string->set_map(i::Heap::short_external_ascii_string_map()); | |
6204 } else { | |
6205 string->set_map(i::Heap::medium_external_ascii_string_map()); | |
6206 } | |
6207 i::ExternalAsciiString* morphed = | |
6208 i::ExternalAsciiString::cast(string); | |
6209 morphed->set_resource(ascii_resource); | |
6210 } | |
6211 } | |
6212 | |
6213 | |
6214 THREADED_TEST(MorphCompositeStringTest) { | |
6215 const char* c_string = "Now is the time for all good men" | |
6216 " to come to the aid of the party"; | |
6217 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | |
6218 { | |
6219 v8::HandleScope scope; | |
6220 LocalContext env; | |
6221 AsciiVectorResource ascii_resource(i::Vector<const char>(c_string, strlen(c_ string))); | |
6222 UC16VectorResource uc16_resource(i::Vector<const uint16_t>(two_byte_string, strlen(c_string))); | |
6223 | |
6224 Local<String> lhs(v8::Utils::ToLocal(i::Factory::NewExternalStringFromAscii( &ascii_resource))); | |
6225 Local<String> rhs(v8::Utils::ToLocal(i::Factory::NewExternalStringFromAscii( &ascii_resource))); | |
6226 | |
6227 env->Global()->Set(v8_str("lhs"), lhs); | |
6228 env->Global()->Set(v8_str("rhs"), rhs); | |
6229 | |
6230 CompileRun( | |
6231 "var cons = lhs + rhs;" | |
6232 "var slice = lhs.substring(1, lhs.length - 1);" | |
6233 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | |
6234 | |
6235 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | |
6236 MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource); | |
6237 | |
6238 // Now do some stuff to make sure the strings are flattened, etc. | |
6239 CompileRun( | |
6240 "/[^a-z]/.test(cons);" | |
6241 "/[^a-z]/.test(slice);" | |
6242 "/[^a-z]/.test(slice_on_cons);"); | |
Lasse Reichstein
2009/05/01 09:47:01
Perhaps add a comment stating what is being tested
| |
6243 const char* expected_cons = | |
6244 "Now is the time for all good men to come to the aid of the party" | |
6245 "Now is the time for all good men to come to the aid of the party"; | |
6246 const char* expected_slice = | |
6247 "ow is the time for all good men to come to the aid of the part"; | |
6248 const char* expected_slice_on_cons = | |
6249 "ow is the time for all good men to come to the aid of the party" | |
6250 "Now is the time for all good men to come to the aid of the part"; | |
6251 CHECK_EQ(String::New(expected_cons), | |
6252 env->Global()->Get(v8_str("cons"))); | |
6253 CHECK_EQ(String::New(expected_slice), | |
6254 env->Global()->Get(v8_str("slice"))); | |
6255 CHECK_EQ(String::New(expected_slice_on_cons), | |
6256 env->Global()->Get(v8_str("slice_on_cons"))); | |
6257 } | |
6258 } | |
6259 | |
6260 | |
6156 class RegExpStringModificationTest { | 6261 class RegExpStringModificationTest { |
6157 public: | 6262 public: |
6158 RegExpStringModificationTest() | 6263 RegExpStringModificationTest() |
6159 : block_(i::OS::CreateSemaphore(0)), | 6264 : block_(i::OS::CreateSemaphore(0)), |
6160 morphs_(0), | 6265 morphs_(0), |
6161 morphs_during_regexp_(0), | 6266 morphs_during_regexp_(0), |
6162 ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)), | 6267 ascii_resource_(i::Vector<const char>("aaaaaaaaaaaaaab", 15)), |
6163 uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {} | 6268 uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {} |
6164 ~RegExpStringModificationTest() { delete block_; } | 6269 ~RegExpStringModificationTest() { delete block_; } |
6165 void RunTest() { | 6270 void RunTest() { |
(...skipping 24 matching lines...) Expand all Loading... | |
6190 { | 6295 { |
6191 v8::Unlocker unlock; | 6296 v8::Unlocker unlock; |
6192 morph_thread.Join(); | 6297 morph_thread.Join(); |
6193 } | 6298 } |
6194 v8::Locker::StopPreemption(); | 6299 v8::Locker::StopPreemption(); |
6195 CHECK(regexp_success_); | 6300 CHECK(regexp_success_); |
6196 CHECK(morph_success_); | 6301 CHECK(morph_success_); |
6197 } | 6302 } |
6198 private: | 6303 private: |
6199 | 6304 |
6200 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | |
6201 public: | |
6202 explicit AsciiVectorResource(i::Vector<const char> vector) | |
6203 : data_(vector) {} | |
6204 virtual ~AsciiVectorResource() {} | |
6205 virtual size_t length() const { return data_.length(); } | |
6206 virtual const char* data() const { return data_.start(); } | |
6207 private: | |
6208 i::Vector<const char> data_; | |
6209 }; | |
6210 class UC16VectorResource : public v8::String::ExternalStringResource { | |
6211 public: | |
6212 explicit UC16VectorResource(i::Vector<const i::uc16> vector) | |
6213 : data_(vector) {} | |
6214 virtual ~UC16VectorResource() {} | |
6215 virtual size_t length() const { return data_.length(); } | |
6216 virtual const i::uc16* data() const { return data_.start(); } | |
6217 private: | |
6218 i::Vector<const i::uc16> data_; | |
6219 }; | |
6220 // Number of string modifications required. | 6305 // Number of string modifications required. |
6221 static const int kRequiredModifications = 5; | 6306 static const int kRequiredModifications = 5; |
6222 static const int kMaxModifications = 100; | 6307 static const int kMaxModifications = 100; |
6223 | 6308 |
6224 class MorphThread : public i::Thread { | 6309 class MorphThread : public i::Thread { |
6225 public: | 6310 public: |
6226 explicit MorphThread(RegExpStringModificationTest* test) | 6311 explicit MorphThread(RegExpStringModificationTest* test) |
6227 : test_(test) {} | 6312 : test_(test) {} |
6228 virtual void Run() { | 6313 virtual void Run() { |
6229 test_->MorphString(); | 6314 test_->MorphString(); |
6230 } | 6315 } |
6231 private: | 6316 private: |
6232 RegExpStringModificationTest* test_; | 6317 RegExpStringModificationTest* test_; |
6233 }; | 6318 }; |
6234 | 6319 |
6235 void MorphString() { | 6320 void MorphString() { |
6236 block_->Wait(); | 6321 block_->Wait(); |
6237 while (morphs_during_regexp_ < kRequiredModifications && | 6322 while (morphs_during_regexp_ < kRequiredModifications && |
6238 morphs_ < kMaxModifications) { | 6323 morphs_ < kMaxModifications) { |
6239 { | 6324 { |
6240 v8::Locker lock; | 6325 v8::Locker lock; |
6241 // Swap string between ascii and two-byte representation. | 6326 // Swap string between ascii and two-byte representation. |
6242 i::String* string = *input_; | 6327 i::String* string = *input_; |
6243 CHECK(i::StringShape(string).IsExternal()); | 6328 MorphAString(string, &ascii_resource_, &uc16_resource_); |
6244 if (i::StringShape(string).IsAsciiRepresentation()) { | |
6245 // Morph external string to be TwoByte string. | |
6246 i::ExternalAsciiString* ext_string = | |
6247 i::ExternalAsciiString::cast(string); | |
6248 i::ExternalTwoByteString* morphed = | |
6249 reinterpret_cast<i::ExternalTwoByteString*>(ext_string); | |
6250 morphed->map()->set_instance_type(i::SHORT_EXTERNAL_STRING_TYPE); | |
6251 morphed->set_resource(&uc16_resource_); | |
6252 } else { | |
6253 // Morph external string to be ASCII string. | |
6254 i::ExternalTwoByteString* ext_string = | |
6255 i::ExternalTwoByteString::cast(string); | |
6256 i::ExternalAsciiString* morphed = | |
6257 reinterpret_cast<i::ExternalAsciiString*>(ext_string); | |
6258 morphed->map()->set_instance_type( | |
6259 i::SHORT_EXTERNAL_ASCII_STRING_TYPE); | |
6260 morphed->set_resource(&ascii_resource_); | |
6261 } | |
6262 morphs_++; | 6329 morphs_++; |
6263 } | 6330 } |
6264 i::OS::Sleep(1); | 6331 i::OS::Sleep(1); |
6265 } | 6332 } |
6266 morph_success_ = true; | 6333 morph_success_ = true; |
6267 } | 6334 } |
6268 | 6335 |
6269 void LongRunningRegExp() { | 6336 void LongRunningRegExp() { |
6270 block_->Signal(); // Enable morphing thread on next preemption. | 6337 block_->Signal(); // Enable morphing thread on next preemption. |
6271 while (morphs_during_regexp_ < kRequiredModifications && | 6338 while (morphs_during_regexp_ < kRequiredModifications && |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6451 // the property | 6518 // the property |
6452 pass_on_get = false; | 6519 pass_on_get = false; |
6453 CHECK_EQ(3, global->Get(some_property)->Int32Value()); | 6520 CHECK_EQ(3, global->Get(some_property)->Int32Value()); |
6454 CHECK_EQ(1, force_set_set_count); | 6521 CHECK_EQ(1, force_set_set_count); |
6455 CHECK_EQ(5, force_set_get_count); | 6522 CHECK_EQ(5, force_set_get_count); |
6456 // The interceptor should also work for other properties | 6523 // The interceptor should also work for other properties |
6457 CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value()); | 6524 CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value()); |
6458 CHECK_EQ(1, force_set_set_count); | 6525 CHECK_EQ(1, force_set_set_count); |
6459 CHECK_EQ(6, force_set_get_count); | 6526 CHECK_EQ(6, force_set_get_count); |
6460 } | 6527 } |
OLD | NEW |