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

Side by Side Diff: test/cctest/test-api.cc

Issue 100249: When strings can change from an ASCII representation to a... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« src/objects-inl.h ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« src/objects-inl.h ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698