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

Side by Side Diff: src/objects.cc

Issue 385004: Remove sliced string string type... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('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 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 Object* String::TryFlatten() { 676 Object* String::TryFlatten() {
677 #ifdef DEBUG 677 #ifdef DEBUG
678 // Do not attempt to flatten in debug mode when allocation is not 678 // Do not attempt to flatten in debug mode when allocation is not
679 // allowed. This is to avoid an assertion failure when allocating. 679 // allowed. This is to avoid an assertion failure when allocating.
680 // Flattening strings is the only case where we always allow 680 // Flattening strings is the only case where we always allow
681 // allocation because no GC is performed if the allocation fails. 681 // allocation because no GC is performed if the allocation fails.
682 if (!Heap::IsAllocationAllowed()) return this; 682 if (!Heap::IsAllocationAllowed()) return this;
683 #endif 683 #endif
684 684
685 switch (StringShape(this).representation_tag()) { 685 switch (StringShape(this).representation_tag()) {
686 case kSlicedStringTag: {
687 SlicedString* ss = SlicedString::cast(this);
688 // The SlicedString constructor should ensure that there are no
689 // SlicedStrings that are constructed directly on top of other
690 // SlicedStrings.
691 String* buf = ss->buffer();
692 ASSERT(!buf->IsSlicedString());
693 Object* ok = buf->TryFlatten();
694 if (ok->IsFailure()) return ok;
695 // Under certain circumstances (TryFlattenIfNotFlat fails in
696 // String::Slice) we can have a cons string under a slice.
697 // In this case we need to get the flat string out of the cons!
698 if (StringShape(String::cast(ok)).IsCons()) {
699 ss->set_buffer(ConsString::cast(ok)->first());
700 }
701 return this;
702 }
703 case kConsStringTag: { 686 case kConsStringTag: {
704 ConsString* cs = ConsString::cast(this); 687 ConsString* cs = ConsString::cast(this);
705 if (cs->second()->length() == 0) { 688 if (cs->second()->length() == 0) {
706 return this; 689 return this;
707 } 690 }
708 // There's little point in putting the flat string in new space if the 691 // There's little point in putting the flat string in new space if the
709 // cons string is in old space. It can never get GCed until there is 692 // cons string is in old space. It can never get GCed until there is
710 // an old space GC. 693 // an old space GC.
711 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED; 694 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED;
712 int len = length(); 695 int len = length();
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 ObjectVisitor* v) { 1111 ObjectVisitor* v) {
1129 // Avoiding <Type>::cast(this) because it accesses the map pointer field. 1112 // Avoiding <Type>::cast(this) because it accesses the map pointer field.
1130 // During GC, the map pointer field is encoded. 1113 // During GC, the map pointer field is encoded.
1131 if (type < FIRST_NONSTRING_TYPE) { 1114 if (type < FIRST_NONSTRING_TYPE) {
1132 switch (type & kStringRepresentationMask) { 1115 switch (type & kStringRepresentationMask) {
1133 case kSeqStringTag: 1116 case kSeqStringTag:
1134 break; 1117 break;
1135 case kConsStringTag: 1118 case kConsStringTag:
1136 reinterpret_cast<ConsString*>(this)->ConsStringIterateBody(v); 1119 reinterpret_cast<ConsString*>(this)->ConsStringIterateBody(v);
1137 break; 1120 break;
1138 case kSlicedStringTag:
1139 reinterpret_cast<SlicedString*>(this)->SlicedStringIterateBody(v);
1140 break;
1141 case kExternalStringTag: 1121 case kExternalStringTag:
1142 if ((type & kStringEncodingMask) == kAsciiStringTag) { 1122 if ((type & kStringEncodingMask) == kAsciiStringTag) {
1143 reinterpret_cast<ExternalAsciiString*>(this)-> 1123 reinterpret_cast<ExternalAsciiString*>(this)->
1144 ExternalAsciiStringIterateBody(v); 1124 ExternalAsciiStringIterateBody(v);
1145 } else { 1125 } else {
1146 reinterpret_cast<ExternalTwoByteString*>(this)-> 1126 reinterpret_cast<ExternalTwoByteString*>(this)->
1147 ExternalTwoByteStringIterateBody(v); 1127 ExternalTwoByteStringIterateBody(v);
1148 } 1128 }
1149 break; 1129 break;
1150 } 1130 }
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after
3564 3544
3565 3545
3566 Vector<const char> String::ToAsciiVector() { 3546 Vector<const char> String::ToAsciiVector() {
3567 ASSERT(IsAsciiRepresentation()); 3547 ASSERT(IsAsciiRepresentation());
3568 ASSERT(IsFlat()); 3548 ASSERT(IsFlat());
3569 3549
3570 int offset = 0; 3550 int offset = 0;
3571 int length = this->length(); 3551 int length = this->length();
3572 StringRepresentationTag string_tag = StringShape(this).representation_tag(); 3552 StringRepresentationTag string_tag = StringShape(this).representation_tag();
3573 String* string = this; 3553 String* string = this;
3574 if (string_tag == kSlicedStringTag) { 3554 if (string_tag == kConsStringTag) {
3575 SlicedString* sliced = SlicedString::cast(string);
3576 offset += sliced->start();
3577 string = sliced->buffer();
3578 string_tag = StringShape(string).representation_tag();
3579 } else if (string_tag == kConsStringTag) {
3580 ConsString* cons = ConsString::cast(string); 3555 ConsString* cons = ConsString::cast(string);
3581 ASSERT(cons->second()->length() == 0); 3556 ASSERT(cons->second()->length() == 0);
3582 string = cons->first(); 3557 string = cons->first();
3583 string_tag = StringShape(string).representation_tag(); 3558 string_tag = StringShape(string).representation_tag();
3584 } 3559 }
3585 if (string_tag == kSeqStringTag) { 3560 if (string_tag == kSeqStringTag) {
3586 SeqAsciiString* seq = SeqAsciiString::cast(string); 3561 SeqAsciiString* seq = SeqAsciiString::cast(string);
3587 char* start = seq->GetChars(); 3562 char* start = seq->GetChars();
3588 return Vector<const char>(start + offset, length); 3563 return Vector<const char>(start + offset, length);
3589 } 3564 }
3590 ASSERT(string_tag == kExternalStringTag); 3565 ASSERT(string_tag == kExternalStringTag);
3591 ExternalAsciiString* ext = ExternalAsciiString::cast(string); 3566 ExternalAsciiString* ext = ExternalAsciiString::cast(string);
3592 const char* start = ext->resource()->data(); 3567 const char* start = ext->resource()->data();
3593 return Vector<const char>(start + offset, length); 3568 return Vector<const char>(start + offset, length);
3594 } 3569 }
3595 3570
3596 3571
3597 Vector<const uc16> String::ToUC16Vector() { 3572 Vector<const uc16> String::ToUC16Vector() {
3598 ASSERT(IsTwoByteRepresentation()); 3573 ASSERT(IsTwoByteRepresentation());
3599 ASSERT(IsFlat()); 3574 ASSERT(IsFlat());
3600 3575
3601 int offset = 0; 3576 int offset = 0;
3602 int length = this->length(); 3577 int length = this->length();
3603 StringRepresentationTag string_tag = StringShape(this).representation_tag(); 3578 StringRepresentationTag string_tag = StringShape(this).representation_tag();
3604 String* string = this; 3579 String* string = this;
3605 if (string_tag == kSlicedStringTag) { 3580 if (string_tag == kConsStringTag) {
3606 SlicedString* sliced = SlicedString::cast(string);
3607 offset += sliced->start();
3608 string = String::cast(sliced->buffer());
3609 string_tag = StringShape(string).representation_tag();
3610 } else if (string_tag == kConsStringTag) {
3611 ConsString* cons = ConsString::cast(string); 3581 ConsString* cons = ConsString::cast(string);
3612 ASSERT(cons->second()->length() == 0); 3582 ASSERT(cons->second()->length() == 0);
3613 string = cons->first(); 3583 string = cons->first();
3614 string_tag = StringShape(string).representation_tag(); 3584 string_tag = StringShape(string).representation_tag();
3615 } 3585 }
3616 if (string_tag == kSeqStringTag) { 3586 if (string_tag == kSeqStringTag) {
3617 SeqTwoByteString* seq = SeqTwoByteString::cast(string); 3587 SeqTwoByteString* seq = SeqTwoByteString::cast(string);
3618 return Vector<const uc16>(seq->GetChars() + offset, length); 3588 return Vector<const uc16>(seq->GetChars() + offset, length);
3619 } 3589 }
3620 ASSERT(string_tag == kExternalStringTag); 3590 ASSERT(string_tag == kExternalStringTag);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3691 3661
3692 3662
3693 const uc16* String::GetTwoByteData(unsigned start) { 3663 const uc16* String::GetTwoByteData(unsigned start) {
3694 ASSERT(!IsAsciiRepresentation()); 3664 ASSERT(!IsAsciiRepresentation());
3695 switch (StringShape(this).representation_tag()) { 3665 switch (StringShape(this).representation_tag()) {
3696 case kSeqStringTag: 3666 case kSeqStringTag:
3697 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); 3667 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
3698 case kExternalStringTag: 3668 case kExternalStringTag:
3699 return ExternalTwoByteString::cast(this)-> 3669 return ExternalTwoByteString::cast(this)->
3700 ExternalTwoByteStringGetData(start); 3670 ExternalTwoByteStringGetData(start);
3701 case kSlicedStringTag: {
3702 SlicedString* sliced_string = SlicedString::cast(this);
3703 String* buffer = sliced_string->buffer();
3704 if (StringShape(buffer).IsCons()) {
3705 ConsString* cs = ConsString::cast(buffer);
3706 // Flattened string.
3707 ASSERT(cs->second()->length() == 0);
3708 buffer = cs->first();
3709 }
3710 return buffer->GetTwoByteData(start + sliced_string->start());
3711 }
3712 case kConsStringTag: 3671 case kConsStringTag:
3713 UNREACHABLE(); 3672 UNREACHABLE();
3714 return NULL; 3673 return NULL;
3715 } 3674 }
3716 UNREACHABLE(); 3675 UNREACHABLE();
3717 return NULL; 3676 return NULL;
3718 } 3677 }
3719 3678
3720 3679
3721 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { 3680 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
3856 rbb, 3815 rbb,
3857 &offset, 3816 &offset,
3858 max_chars > rbb->capacity ? rbb->capacity : max_chars); 3817 max_chars > rbb->capacity ? rbb->capacity : max_chars);
3859 *offset_ptr = offset + offset_correction; 3818 *offset_ptr = offset + offset_correction;
3860 return rbb->util_buffer; 3819 return rbb->util_buffer;
3861 } 3820 }
3862 } 3821 }
3863 } 3822 }
3864 3823
3865 3824
3866 const unibrow::byte* SlicedString::SlicedStringReadBlock(ReadBlockBuffer* rbb,
3867 unsigned* offset_ptr,
3868 unsigned max_chars) {
3869 String* backing = buffer();
3870 unsigned offset = start() + *offset_ptr;
3871 unsigned length = backing->length();
3872 if (max_chars > length - offset) {
3873 max_chars = length - offset;
3874 }
3875 const unibrow::byte* answer =
3876 String::ReadBlock(backing, rbb, &offset, max_chars);
3877 *offset_ptr = offset - start();
3878 return answer;
3879 }
3880
3881
3882 uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) { 3825 uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
3883 ASSERT(index >= 0 && index < length()); 3826 ASSERT(index >= 0 && index < length());
3884 return resource()->data()[index]; 3827 return resource()->data()[index];
3885 } 3828 }
3886 3829
3887 3830
3888 const unibrow::byte* ExternalAsciiString::ExternalAsciiStringReadBlock( 3831 const unibrow::byte* ExternalAsciiString::ExternalAsciiStringReadBlock(
3889 unsigned* remaining, 3832 unsigned* remaining,
3890 unsigned* offset_ptr, 3833 unsigned* offset_ptr,
3891 unsigned max_chars) { 3834 unsigned max_chars) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3995 SeqTwoByteString* str = SeqTwoByteString::cast(input); 3938 SeqTwoByteString* str = SeqTwoByteString::cast(input);
3996 str->SeqTwoByteStringReadBlockIntoBuffer(rbb, 3939 str->SeqTwoByteStringReadBlockIntoBuffer(rbb,
3997 offset_ptr, 3940 offset_ptr,
3998 max_chars); 3941 max_chars);
3999 return rbb->util_buffer; 3942 return rbb->util_buffer;
4000 } 3943 }
4001 case kConsStringTag: 3944 case kConsStringTag:
4002 return ConsString::cast(input)->ConsStringReadBlock(rbb, 3945 return ConsString::cast(input)->ConsStringReadBlock(rbb,
4003 offset_ptr, 3946 offset_ptr,
4004 max_chars); 3947 max_chars);
4005 case kSlicedStringTag:
4006 return SlicedString::cast(input)->SlicedStringReadBlock(rbb,
4007 offset_ptr,
4008 max_chars);
4009 case kExternalStringTag: 3948 case kExternalStringTag:
4010 if (input->IsAsciiRepresentation()) { 3949 if (input->IsAsciiRepresentation()) {
4011 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock( 3950 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock(
4012 &rbb->remaining, 3951 &rbb->remaining,
4013 offset_ptr, 3952 offset_ptr,
4014 max_chars); 3953 max_chars);
4015 } else { 3954 } else {
4016 ExternalTwoByteString::cast(input)-> 3955 ExternalTwoByteString::cast(input)->
4017 ExternalTwoByteStringReadBlockIntoBuffer(rbb, 3956 ExternalTwoByteStringReadBlockIntoBuffer(rbb,
4018 offset_ptr, 3957 offset_ptr,
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4141 SeqTwoByteString::cast(input)->SeqTwoByteStringReadBlockIntoBuffer(rbb, 4080 SeqTwoByteString::cast(input)->SeqTwoByteStringReadBlockIntoBuffer(rbb,
4142 offset_ptr, 4081 offset_ptr,
4143 max_chars); 4082 max_chars);
4144 return; 4083 return;
4145 } 4084 }
4146 case kConsStringTag: 4085 case kConsStringTag:
4147 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb, 4086 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb,
4148 offset_ptr, 4087 offset_ptr,
4149 max_chars); 4088 max_chars);
4150 return; 4089 return;
4151 case kSlicedStringTag:
4152 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb,
4153 offset_ptr,
4154 max_chars);
4155 return;
4156 case kExternalStringTag: 4090 case kExternalStringTag:
4157 if (input->IsAsciiRepresentation()) { 4091 if (input->IsAsciiRepresentation()) {
4158 ExternalAsciiString::cast(input)-> 4092 ExternalAsciiString::cast(input)->
4159 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); 4093 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
4160 } else { 4094 } else {
4161 ExternalTwoByteString::cast(input)-> 4095 ExternalTwoByteString::cast(input)->
4162 ExternalTwoByteStringReadBlockIntoBuffer(rbb, 4096 ExternalTwoByteStringReadBlockIntoBuffer(rbb,
4163 offset_ptr, 4097 offset_ptr,
4164 max_chars); 4098 max_chars);
4165 } 4099 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4260 offset_correction += left_length; 4194 offset_correction += left_length;
4261 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars); 4195 String::ReadBlockIntoBuffer(right, rbb, &offset, max_chars);
4262 } 4196 }
4263 *offset_ptr = offset + offset_correction; 4197 *offset_ptr = offset + offset_correction;
4264 return; 4198 return;
4265 } 4199 }
4266 } 4200 }
4267 } 4201 }
4268 4202
4269 4203
4270 void SlicedString::SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
4271 unsigned* offset_ptr,
4272 unsigned max_chars) {
4273 String* backing = buffer();
4274 unsigned offset = start() + *offset_ptr;
4275 unsigned length = backing->length();
4276 if (max_chars > length - offset) {
4277 max_chars = length - offset;
4278 }
4279 String::ReadBlockIntoBuffer(backing, rbb, &offset, max_chars);
4280 *offset_ptr = offset - start();
4281 }
4282
4283
4284 void ConsString::ConsStringIterateBody(ObjectVisitor* v) { 4204 void ConsString::ConsStringIterateBody(ObjectVisitor* v) {
4285 IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize); 4205 IteratePointers(v, kFirstOffset, kSecondOffset + kPointerSize);
4286 } 4206 }
4287 4207
4288 4208
4289 void JSGlobalPropertyCell::JSGlobalPropertyCellIterateBody(ObjectVisitor* v) { 4209 void JSGlobalPropertyCell::JSGlobalPropertyCellIterateBody(ObjectVisitor* v) {
4290 IteratePointers(v, kValueOffset, kValueOffset + kPointerSize); 4210 IteratePointers(v, kValueOffset, kValueOffset + kPointerSize);
4291 } 4211 }
4292 4212
4293 4213
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4352 SeqAsciiString::cast(source)->GetChars() + from, 4272 SeqAsciiString::cast(source)->GetChars() + from,
4353 to - from); 4273 to - from);
4354 return; 4274 return;
4355 } 4275 }
4356 case kTwoByteStringTag | kSeqStringTag: { 4276 case kTwoByteStringTag | kSeqStringTag: {
4357 CopyChars(sink, 4277 CopyChars(sink,
4358 SeqTwoByteString::cast(source)->GetChars() + from, 4278 SeqTwoByteString::cast(source)->GetChars() + from,
4359 to - from); 4279 to - from);
4360 return; 4280 return;
4361 } 4281 }
4362 case kAsciiStringTag | kSlicedStringTag:
4363 case kTwoByteStringTag | kSlicedStringTag: {
4364 SlicedString* sliced_string = SlicedString::cast(source);
4365 int start = sliced_string->start();
4366 from += start;
4367 to += start;
4368 source = String::cast(sliced_string->buffer());
4369 break;
4370 }
4371 case kAsciiStringTag | kConsStringTag: 4282 case kAsciiStringTag | kConsStringTag:
4372 case kTwoByteStringTag | kConsStringTag: { 4283 case kTwoByteStringTag | kConsStringTag: {
4373 ConsString* cons_string = ConsString::cast(source); 4284 ConsString* cons_string = ConsString::cast(source);
4374 String* first = cons_string->first(); 4285 String* first = cons_string->first();
4375 int boundary = first->length(); 4286 int boundary = first->length();
4376 if (to - boundary >= boundary - from) { 4287 if (to - boundary >= boundary - from) {
4377 // Right hand side is longer. Recurse over left. 4288 // Right hand side is longer. Recurse over left.
4378 if (from < boundary) { 4289 if (from < boundary) {
4379 WriteToFlat(first, sink, from, boundary); 4290 WriteToFlat(first, sink, from, boundary);
4380 sink += boundary - from; 4291 sink += boundary - from;
(...skipping 15 matching lines...) Expand all
4396 } 4307 }
4397 source = first; 4308 source = first;
4398 } 4309 }
4399 break; 4310 break;
4400 } 4311 }
4401 } 4312 }
4402 } 4313 }
4403 } 4314 }
4404 4315
4405 4316
4406 void SlicedString::SlicedStringIterateBody(ObjectVisitor* v) {
4407 IteratePointer(v, kBufferOffset);
4408 }
4409
4410 #define FIELD_ADDR(p, offset) \ 4317 #define FIELD_ADDR(p, offset) \
4411 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) 4318 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
4412 4319
4413 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) { 4320 void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4414 typedef v8::String::ExternalAsciiStringResource Resource; 4321 typedef v8::String::ExternalAsciiStringResource Resource;
4415 v->VisitExternalAsciiString( 4322 v->VisitExternalAsciiString(
4416 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); 4323 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4417 } 4324 }
4418 4325
4419 4326
4420 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) { 4327 void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4421 typedef v8::String::ExternalStringResource Resource; 4328 typedef v8::String::ExternalStringResource Resource;
4422 v->VisitExternalTwoByteString( 4329 v->VisitExternalTwoByteString(
4423 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset))); 4330 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4424 } 4331 }
4425 4332
4426 #undef FIELD_ADDR 4333 #undef FIELD_ADDR
4427 4334
4428 uint16_t SlicedString::SlicedStringGet(int index) {
4429 ASSERT(index >= 0 && index < this->length());
4430 // Delegate to the buffer string.
4431 String* underlying = buffer();
4432 return underlying->Get(start() + index);
4433 }
4434
4435
4436 template <typename IteratorA, typename IteratorB> 4335 template <typename IteratorA, typename IteratorB>
4437 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { 4336 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) {
4438 // General slow case check. We know that the ia and ib iterators 4337 // General slow case check. We know that the ia and ib iterators
4439 // have the same length. 4338 // have the same length.
4440 while (ia->has_more()) { 4339 while (ia->has_more()) {
4441 uc32 ca = ia->GetNext(); 4340 uc32 ca = ia->GetNext();
4442 uc32 cb = ib->GetNext(); 4341 uc32 cb = ib->GetNext();
4443 if (ca != cb) 4342 if (ca != cb)
4444 return false; 4343 return false;
4445 } 4344 }
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
4724 // Process the remaining characters without updating the array 4623 // Process the remaining characters without updating the array
4725 // index. 4624 // index.
4726 while (buffer->has_more()) { 4625 while (buffer->has_more()) {
4727 hasher.AddCharacterNoIndex(buffer->GetNext()); 4626 hasher.AddCharacterNoIndex(buffer->GetNext());
4728 } 4627 }
4729 4628
4730 return hasher.GetHashField(); 4629 return hasher.GetHashField();
4731 } 4630 }
4732 4631
4733 4632
4734 Object* String::Slice(int start, int end) { 4633 Object* String::SubString(int start, int end) {
4735 if (start == 0 && end == length()) return this; 4634 if (start == 0 && end == length()) return this;
4736 if (StringShape(this).representation_tag() == kSlicedStringTag) { 4635 Object* result = Heap::AllocateSubString(this, start, end);
4737 // Translate slices of a SlicedString into slices of the 4636 return result;
4738 // underlying string buffer.
4739 SlicedString* str = SlicedString::cast(this);
4740 String* buf = str->buffer();
4741 return Heap::AllocateSlicedString(buf,
4742 str->start() + start,
4743 str->start() + end);
4744 }
4745 Object* result = Heap::AllocateSlicedString(this, start, end);
4746 if (result->IsFailure()) {
4747 return result;
4748 }
4749 // Due to the way we retry after GC on allocation failure we are not allowed
4750 // to fail on allocation after this point. This is the one-allocation rule.
4751
4752 // Try to flatten a cons string that is under the sliced string.
4753 // This is to avoid memory leaks and possible stack overflows caused by
4754 // building 'towers' of sliced strings on cons strings.
4755 // This may fail due to an allocation failure (when a GC is needed), but it
4756 // will succeed often enough to avoid the problem. We only have to do this
4757 // if Heap::AllocateSlicedString actually returned a SlicedString. It will
4758 // return flat strings for small slices for efficiency reasons.
4759 String* answer = String::cast(result);
4760 if (StringShape(answer).IsSliced() &&
4761 StringShape(this).representation_tag() == kConsStringTag) {
4762 TryFlatten();
4763 // If the flatten succeeded we might as well make the sliced string point
4764 // to the flat string rather than the cons string.
4765 String* second = ConsString::cast(this)->second();
4766 if (second->length() == 0) {
4767 SlicedString::cast(answer)->set_buffer(ConsString::cast(this)->first());
4768 }
4769 }
4770 return answer;
4771 } 4637 }
4772 4638
4773 4639
4774 void String::PrintOn(FILE* file) { 4640 void String::PrintOn(FILE* file) {
4775 int length = this->length(); 4641 int length = this->length();
4776 for (int i = 0; i < length; i++) { 4642 for (int i = 0; i < length; i++) {
4777 fprintf(file, "%c", Get(i)); 4643 fprintf(file, "%c", Get(i));
4778 } 4644 }
4779 } 4645 }
4780 4646
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5013 // without any allocation in the heap. 4879 // without any allocation in the heap.
5014 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator, 4880 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
5015 int max_length) { 4881 int max_length) {
5016 // For some native functions there is no source. 4882 // For some native functions there is no source.
5017 if (script()->IsUndefined() || 4883 if (script()->IsUndefined() ||
5018 Script::cast(script())->source()->IsUndefined()) { 4884 Script::cast(script())->source()->IsUndefined()) {
5019 accumulator->Add("<No Source>"); 4885 accumulator->Add("<No Source>");
5020 return; 4886 return;
5021 } 4887 }
5022 4888
5023 // Get the slice of the source for this function. 4889 // Get the source for the script which this function came from.
5024 // Don't use String::cast because we don't want more assertion errors while 4890 // Don't use String::cast because we don't want more assertion errors while
5025 // we are already creating a stack dump. 4891 // we are already creating a stack dump.
5026 String* script_source = 4892 String* script_source =
5027 reinterpret_cast<String*>(Script::cast(script())->source()); 4893 reinterpret_cast<String*>(Script::cast(script())->source());
5028 4894
5029 if (!script_source->LooksValid()) { 4895 if (!script_source->LooksValid()) {
5030 accumulator->Add("<Invalid Source>"); 4896 accumulator->Add("<Invalid Source>");
5031 return; 4897 return;
5032 } 4898 }
5033 4899
(...skipping 3299 matching lines...) Expand 10 before | Expand all | Expand 10 after
8333 if (break_point_objects()->IsUndefined()) return 0; 8199 if (break_point_objects()->IsUndefined()) return 0;
8334 // Single beak point. 8200 // Single beak point.
8335 if (!break_point_objects()->IsFixedArray()) return 1; 8201 if (!break_point_objects()->IsFixedArray()) return 1;
8336 // Multiple break points. 8202 // Multiple break points.
8337 return FixedArray::cast(break_point_objects())->length(); 8203 return FixedArray::cast(break_point_objects())->length();
8338 } 8204 }
8339 #endif 8205 #endif
8340 8206
8341 8207
8342 } } // namespace v8::internal 8208 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698