| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 } | 192 } |
| 193 | 193 |
| 194 // __defineGetter__ callback | 194 // __defineGetter__ callback |
| 195 if (structure->IsFixedArray()) { | 195 if (structure->IsFixedArray()) { |
| 196 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 196 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); |
| 197 if (getter->IsJSFunction()) { | 197 if (getter->IsJSFunction()) { |
| 198 HandleScope scope; | 198 HandleScope scope; |
| 199 Handle<JSFunction> fun(JSFunction::cast(getter)); | 199 Handle<JSFunction> fun(JSFunction::cast(getter)); |
| 200 Handle<Object> self(receiver); | 200 Handle<Object> self(receiver); |
| 201 bool has_pending_exception; | 201 bool has_pending_exception; |
| 202 Object* result = | 202 Handle<Object> result = |
| 203 *Execution::Call(fun, self, 0, NULL, &has_pending_exception); | 203 Execution::Call(fun, self, 0, NULL, &has_pending_exception); |
| 204 // Check for pending exception and return the result. | 204 // Check for pending exception and return the result. |
| 205 if (has_pending_exception) return Failure::Exception(); | 205 if (has_pending_exception) return Failure::Exception(); |
| 206 return result; | 206 return *result; |
| 207 } | 207 } |
| 208 // Getter is not a function. | 208 // Getter is not a function. |
| 209 return Heap::undefined_value(); | 209 return Heap::undefined_value(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 UNREACHABLE(); | 212 UNREACHABLE(); |
| 213 return 0; | 213 return 0; |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| (...skipping 3493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 } else { | 3710 } else { |
| 3711 return string->Get(shape, index); | 3711 return string->Get(shape, index); |
| 3712 } | 3712 } |
| 3713 } | 3713 } |
| 3714 | 3714 |
| 3715 UNREACHABLE(); | 3715 UNREACHABLE(); |
| 3716 return 0; | 3716 return 0; |
| 3717 } | 3717 } |
| 3718 | 3718 |
| 3719 | 3719 |
| 3720 Object* SlicedString::SlicedStringFlatten() { | |
| 3721 // The SlicedString constructor should ensure that there are no | |
| 3722 // SlicedStrings that are constructed directly on top of other | |
| 3723 // SlicedStrings. | |
| 3724 String* buf = String::cast(buffer()); | |
| 3725 StringShape buf_shape(buf); | |
| 3726 ASSERT(!buf_shape.IsSliced()); | |
| 3727 if (buf_shape.IsCons()) { | |
| 3728 Object* ok = buf->Flatten(buf_shape); | |
| 3729 if (ok->IsFailure()) return ok; | |
| 3730 } | |
| 3731 return this; | |
| 3732 } | |
| 3733 | |
| 3734 | |
| 3735 template <typename sinkchar> | 3720 template <typename sinkchar> |
| 3736 void String::WriteToFlat(String* src, | 3721 void String::WriteToFlat(String* src, |
| 3737 StringShape src_shape, | 3722 StringShape src_shape, |
| 3738 sinkchar* sink, | 3723 sinkchar* sink, |
| 3739 int f, | 3724 int f, |
| 3740 int t) { | 3725 int t) { |
| 3741 String* source = src; | 3726 String* source = src; |
| 3742 StringShape shape = src_shape; | 3727 StringShape shape = src_shape; |
| 3743 int from = f; | 3728 int from = f; |
| 3744 int to = t; | 3729 int to = t; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3856 const Char* pa = a.start(); | 3841 const Char* pa = a.start(); |
| 3857 const Char* pb = b.start(); | 3842 const Char* pb = b.start(); |
| 3858 int i = 0; | 3843 int i = 0; |
| 3859 #ifndef CAN_READ_UNALIGNED | 3844 #ifndef CAN_READ_UNALIGNED |
| 3860 // If this architecture isn't comfortable reading unaligned ints | 3845 // If this architecture isn't comfortable reading unaligned ints |
| 3861 // then we have to check that the strings are aligned before | 3846 // then we have to check that the strings are aligned before |
| 3862 // comparing them blockwise. | 3847 // comparing them blockwise. |
| 3863 const int kAlignmentMask = sizeof(uint32_t) - 1; // NOLINT | 3848 const int kAlignmentMask = sizeof(uint32_t) - 1; // NOLINT |
| 3864 uint32_t pa_addr = reinterpret_cast<uint32_t>(pa); | 3849 uint32_t pa_addr = reinterpret_cast<uint32_t>(pa); |
| 3865 uint32_t pb_addr = reinterpret_cast<uint32_t>(pb); | 3850 uint32_t pb_addr = reinterpret_cast<uint32_t>(pb); |
| 3866 if ((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask) == 0) { | 3851 if (((pa_addr & kAlignmentMask) | (pb_addr & kAlignmentMask)) == 0) { |
| 3867 #endif | 3852 #endif |
| 3868 const int kStepSize = sizeof(int) / sizeof(Char); // NOLINT | 3853 const int kStepSize = sizeof(int) / sizeof(Char); // NOLINT |
| 3869 int endpoint = length - kStepSize; | 3854 int endpoint = length - kStepSize; |
| 3870 // Compare blocks until we reach near the end of the string. | 3855 // Compare blocks until we reach near the end of the string. |
| 3871 for (; i <= endpoint; i += kStepSize) { | 3856 for (; i <= endpoint; i += kStepSize) { |
| 3872 uint32_t wa = *reinterpret_cast<const uint32_t*>(pa + i); | 3857 uint32_t wa = *reinterpret_cast<const uint32_t*>(pa + i); |
| 3873 uint32_t wb = *reinterpret_cast<const uint32_t*>(pb + i); | 3858 uint32_t wb = *reinterpret_cast<const uint32_t*>(pb + i); |
| 3874 if (wa != wb) { | 3859 if (wa != wb) { |
| 3875 return false; | 3860 return false; |
| 3876 } | 3861 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3968 } | 3953 } |
| 3969 } | 3954 } |
| 3970 } else { | 3955 } else { |
| 3971 string_compare_buffer_a.Reset(0, this); | 3956 string_compare_buffer_a.Reset(0, this); |
| 3972 return CompareStringContentsPartial(&string_compare_buffer_a, other); | 3957 return CompareStringContentsPartial(&string_compare_buffer_a, other); |
| 3973 } | 3958 } |
| 3974 } | 3959 } |
| 3975 | 3960 |
| 3976 | 3961 |
| 3977 bool String::MarkAsUndetectable() { | 3962 bool String::MarkAsUndetectable() { |
| 3978 StringShape shape(this); | 3963 if (StringShape(this).IsSymbol()) return false; |
| 3979 if (shape.IsSymbol()) return false; | |
| 3980 | 3964 |
| 3981 Map* map = this->map(); | 3965 Map* map = this->map(); |
| 3982 if (map == Heap::short_string_map()) { | 3966 if (map == Heap::short_string_map()) { |
| 3983 this->set_map(Heap::undetectable_short_string_map()); | 3967 this->set_map(Heap::undetectable_short_string_map()); |
| 3984 return true; | 3968 return true; |
| 3985 } else if (map == Heap::medium_string_map()) { | 3969 } else if (map == Heap::medium_string_map()) { |
| 3986 this->set_map(Heap::undetectable_medium_string_map()); | 3970 this->set_map(Heap::undetectable_medium_string_map()); |
| 3987 return true; | 3971 return true; |
| 3988 } else if (map == Heap::long_string_map()) { | 3972 } else if (map == Heap::long_string_map()) { |
| 3989 this->set_map(Heap::undetectable_long_string_map()); | 3973 this->set_map(Heap::undetectable_long_string_map()); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 // Process the remaining characters without updating the array | 4111 // Process the remaining characters without updating the array |
| 4128 // index. | 4112 // index. |
| 4129 while (buffer->has_more()) { | 4113 while (buffer->has_more()) { |
| 4130 hasher.AddCharacterNoIndex(buffer->GetNext()); | 4114 hasher.AddCharacterNoIndex(buffer->GetNext()); |
| 4131 } | 4115 } |
| 4132 | 4116 |
| 4133 return hasher.GetHashField(); | 4117 return hasher.GetHashField(); |
| 4134 } | 4118 } |
| 4135 | 4119 |
| 4136 | 4120 |
| 4137 Object* String::Slice(StringShape shape, int start, int end) { | 4121 Object* String::Slice(int start, int end) { |
| 4122 StringShape shape(this); |
| 4138 if (start == 0 && end == length(shape)) return this; | 4123 if (start == 0 && end == length(shape)) return this; |
| 4139 if (shape.representation_tag() == kSlicedStringTag) { | 4124 if (shape.representation_tag() == kSlicedStringTag) { |
| 4140 // Translate slices of a SlicedString into slices of the | 4125 // Translate slices of a SlicedString into slices of the |
| 4141 // underlying string buffer. | 4126 // underlying string buffer. |
| 4142 SlicedString* str = SlicedString::cast(this); | 4127 SlicedString* str = SlicedString::cast(this); |
| 4143 String* buf = str->buffer(); | 4128 String* buf = str->buffer(); |
| 4144 return Heap::AllocateSlicedString(buf, | 4129 return Heap::AllocateSlicedString(buf, |
| 4145 StringShape(buf), | |
| 4146 str->start() + start, | 4130 str->start() + start, |
| 4147 str->start() + end); | 4131 str->start() + end); |
| 4148 } | 4132 } |
| 4149 Object* result = Heap::AllocateSlicedString(this, shape, start, end); | 4133 Object* result = Heap::AllocateSlicedString(this, start, end); |
| 4150 if (result->IsFailure()) { | 4134 if (result->IsFailure()) { |
| 4151 return result; | 4135 return result; |
| 4152 } | 4136 } |
| 4153 // Due to the way we retry after GC on allocation failure we are not allowed | 4137 // Due to the way we retry after GC on allocation failure we are not allowed |
| 4154 // to fail on allocation after this point. This is the one-allocation rule. | 4138 // to fail on allocation after this point. This is the one-allocation rule. |
| 4155 | 4139 |
| 4156 // Try to flatten a cons string that is under the sliced string. | 4140 // Try to flatten a cons string that is under the sliced string. |
| 4157 // This is to avoid memory leaks and possible stack overflows caused by | 4141 // This is to avoid memory leaks and possible stack overflows caused by |
| 4158 // building 'towers' of sliced strings on cons strings. | 4142 // building 'towers' of sliced strings on cons strings. |
| 4159 // This may fail due to an allocation failure (when a GC is needed), but it | 4143 // This may fail due to an allocation failure (when a GC is needed), but it |
| (...skipping 2760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6920 // No break point. | 6904 // No break point. |
| 6921 if (break_point_objects()->IsUndefined()) return 0; | 6905 if (break_point_objects()->IsUndefined()) return 0; |
| 6922 // Single beak point. | 6906 // Single beak point. |
| 6923 if (!break_point_objects()->IsFixedArray()) return 1; | 6907 if (!break_point_objects()->IsFixedArray()) return 1; |
| 6924 // Multiple break points. | 6908 // Multiple break points. |
| 6925 return FixedArray::cast(break_point_objects())->length(); | 6909 return FixedArray::cast(break_point_objects())->length(); |
| 6926 } | 6910 } |
| 6927 | 6911 |
| 6928 | 6912 |
| 6929 } } // namespace v8::internal | 6913 } } // namespace v8::internal |
| OLD | NEW |