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

Side by Side Diff: src/runtime.cc

Issue 5443001: Move quoting of a JSON string to a specialized runtime function. (Closed)
Patch Set: Remove TODO, add counters to track behavior. Created 10 years 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
« no previous file with comments | « src/runtime.h ('k') | src/v8-counters.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 4506 matching lines...) Expand 10 before | Expand all | Expand 10 after
4517 int dest_position = 0; 4517 int dest_position = 0;
4518 for (int i = 0; i < length; dest_position++) { 4518 for (int i = 0; i < length; dest_position++) {
4519 int step; 4519 int step;
4520 destination->Set(dest_position, Unescape(source, i, length, &step)); 4520 destination->Set(dest_position, Unescape(source, i, length, &step));
4521 i += step; 4521 i += step;
4522 } 4522 }
4523 return destination; 4523 return destination;
4524 } 4524 }
4525 4525
4526 4526
4527 static const char* const JsonQuotes[128] = {
4528 "\\u0000", "\\u0001", "\\u0002", "\\u0003",
4529 "\\u0004", "\\u0005", "\\u0006", "\\u0007",
4530 "\\b", "\\t", "\\n", "\\u000b",
4531 "\\f", "\\r", "\\u000e", "\\u000f",
4532 "\\u0010", "\\u0011", "\\u0012", "\\u0013",
4533 "\\u0014", "\\u0015", "\\u0016", "\\u0017",
4534 "\\u0018", "\\u0019", "\\u001a", "\\u001b",
4535 "\\u001c", "\\u001d", "\\u001e", "\\u001f",
4536 NULL, NULL, "\\\"", NULL,
4537 NULL, NULL, NULL, NULL,
4538 NULL, NULL, NULL, NULL,
4539 NULL, NULL, NULL, NULL,
4540 NULL, NULL, NULL, NULL,
4541 NULL, NULL, NULL, NULL,
4542 NULL, NULL, NULL, NULL,
4543 NULL, NULL, NULL, NULL,
4544 NULL, NULL, NULL, NULL,
4545 NULL, NULL, NULL, NULL,
4546 NULL, NULL, NULL, NULL,
4547 NULL, NULL, NULL, NULL,
4548 NULL, NULL, NULL, NULL,
4549 NULL, NULL, NULL, NULL,
4550 NULL, NULL, NULL, NULL,
4551 "\\\\", NULL, NULL, NULL,
4552 NULL, NULL, NULL, NULL,
4553 NULL, NULL, NULL, NULL,
4554 NULL, NULL, NULL, NULL,
4555 NULL, NULL, NULL, NULL,
4556 NULL, NULL, NULL, NULL,
4557 NULL, NULL, NULL, NULL,
4558 NULL, NULL, NULL, NULL,
4559 NULL, NULL, NULL, NULL,
4560 };
4561
4562
4563 static const byte JsonQuoteLengths[128] = {
4564 6, 6, 6, 6, 6, 6, 6, 6,
4565 2, 2, 2, 6, 2, 2, 6, 6,
4566 6, 6, 6, 6, 6, 6, 6, 6,
4567 6, 6, 6, 6, 6, 6, 6, 6,
4568 1, 1, 2, 1, 1, 1, 1, 1,
4569 1, 1, 1, 1, 1, 1, 1, 1,
4570 1, 1, 1, 1, 1, 1, 1, 1,
4571 1, 1, 1, 1, 1, 1, 1, 1,
4572 1, 1, 1, 1, 1, 1, 1, 1,
4573 1, 1, 1, 1, 1, 1, 1, 1,
4574 1, 1, 1, 1, 1, 1, 1, 1,
4575 1, 1, 1, 1, 2, 1, 1, 1,
4576 1, 1, 1, 1, 1, 1, 1, 1,
4577 1, 1, 1, 1, 1, 1, 1, 1,
4578 1, 1, 1, 1, 1, 1, 1, 1,
4579 1, 1, 1, 1, 1, 1, 1, 1,
4580 };
4581
4582
4583 template <typename Char>
4584 Char* WriteString(Char* dst, const char* src_string) {
4585 char c;
4586 for (c = *src_string; c; c = *src_string) {
4587 *dst = c;
4588 dst++;
4589 src_string++;
4590 }
4591 return dst;
4592 }
4593
4594
4595 template <typename StringType>
4596 MaybeObject* AllocateRawString(int length);
4597
4598
4599 template <>
4600 MaybeObject* AllocateRawString<SeqTwoByteString>(int length) {
4601 return Heap::AllocateRawTwoByteString(length);
4602 }
4603
4604
4605 template <>
4606 MaybeObject* AllocateRawString<SeqAsciiString>(int length) {
4607 return Heap::AllocateRawAsciiString(length);
4608 }
4609
4610
4611 template <typename Char, typename StringType>
4612 static MaybeObject* QuoteJsonString(String* original,
4613 Vector<const Char> characters) {
4614 int length = characters.length();
4615 int quoted_length = 0;
4616 for (int i = 0; i < length; i++) {
4617 unsigned int c = characters[i];
4618 if (sizeof(Char) > 1u) {
4619 quoted_length +=
4620 (c >= sizeof(JsonQuoteLengths)) ? 1 : JsonQuoteLengths[c];
4621 } else {
4622 quoted_length += JsonQuoteLengths[c];
4623 }
4624 }
4625 if (quoted_length == length) {
4626 return Heap::undefined_value();
4627 }
4628 Counters::quote_json_char_count.Increment(length);
4629
4630 // Add space for quotes.
4631 quoted_length += 2;
4632
4633 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length);
4634 Object* new_object;
4635 if (!new_alloc->ToObject(&new_object)) {
4636 Counters::quote_json_char_recount.Increment(length);
4637 return new_alloc;
4638 }
4639 StringType* new_string = StringType::cast(new_object);
4640
4641
4642 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
4643 Char* write_cursor = reinterpret_cast<Char*>(
4644 new_string->address() + SeqAsciiString::kHeaderSize);
4645 *(write_cursor++) = '"';
4646 const Char* read_cursor = characters.start();
4647 const Char* end = read_cursor + length;
4648 while (read_cursor < end) {
4649 Char c = *(read_cursor++);
4650 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= sizeof(JsonQuotes)) {
4651 *(write_cursor++) = c;
4652 } else {
4653 const char* replacement = JsonQuotes[static_cast<unsigned>(c)];
4654 if (!replacement) {
4655 *(write_cursor++) = c;
4656 } else {
4657 write_cursor = WriteString(write_cursor, replacement);
4658 }
4659 }
4660 }
4661 *(write_cursor++) = '"';
4662 ASSERT_EQ(SeqAsciiString::kHeaderSize + quoted_length * sizeof(Char),
4663 reinterpret_cast<Address>(write_cursor) - new_string->address());
4664 return new_string;
4665 }
4666
4667
4668 static MaybeObject* Runtime_QuoteJSONString(Arguments args) {
4669 NoHandleAllocation ha;
4670 CONVERT_CHECKED(String, str, args[0]);
4671 if (!str->IsFlat()) {
4672 MaybeObject* try_flatten = str->TryFlatten();
4673 Object* flat;
4674 if (!try_flatten->ToObject(&flat)) {
4675 return try_flatten;
4676 }
4677 str = String::cast(flat);
4678 ASSERT(str->IsFlat());
4679 }
4680 if (str->IsTwoByteRepresentation()) {
4681 return QuoteJsonString<uc16, SeqTwoByteString>(str, str->ToUC16Vector());
4682 } else {
4683 return QuoteJsonString<char, SeqAsciiString>(str, str->ToAsciiVector());
4684 }
4685 }
4686
4687
4527 static MaybeObject* Runtime_StringParseInt(Arguments args) { 4688 static MaybeObject* Runtime_StringParseInt(Arguments args) {
4528 NoHandleAllocation ha; 4689 NoHandleAllocation ha;
4529 4690
4530 CONVERT_CHECKED(String, s, args[0]); 4691 CONVERT_CHECKED(String, s, args[0]);
4531 CONVERT_SMI_CHECKED(radix, args[1]); 4692 CONVERT_SMI_CHECKED(radix, args[1]);
4532 4693
4533 s->TryFlatten(); 4694 s->TryFlatten();
4534 4695
4535 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); 4696 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
4536 double value = StringToInt(s, radix); 4697 double value = StringToInt(s, radix);
(...skipping 5788 matching lines...) Expand 10 before | Expand all | Expand 10 after
10325 } else { 10486 } else {
10326 // Handle last resort GC and make sure to allow future allocations 10487 // Handle last resort GC and make sure to allow future allocations
10327 // to grow the heap without causing GCs (if possible). 10488 // to grow the heap without causing GCs (if possible).
10328 Counters::gc_last_resort_from_js.Increment(); 10489 Counters::gc_last_resort_from_js.Increment();
10329 Heap::CollectAllGarbage(false); 10490 Heap::CollectAllGarbage(false);
10330 } 10491 }
10331 } 10492 }
10332 10493
10333 10494
10334 } } // namespace v8::internal 10495 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698