| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2925 | 2925 |
| 2926 // Try to flatten before operating on the string. | 2926 // Try to flatten before operating on the string. |
| 2927 name->TryFlatten(); | 2927 name->TryFlatten(); |
| 2928 | 2928 |
| 2929 if (!CanSetCallback(name)) { | 2929 if (!CanSetCallback(name)) { |
| 2930 return Heap::undefined_value(); | 2930 return Heap::undefined_value(); |
| 2931 } | 2931 } |
| 2932 | 2932 |
| 2933 uint32_t index = 0; | 2933 uint32_t index = 0; |
| 2934 bool is_element = name->AsArrayIndex(&index); | 2934 bool is_element = name->AsArrayIndex(&index); |
| 2935 if (is_element && IsJSArray()) return Heap::undefined_value(); | |
| 2936 | 2935 |
| 2937 if (is_element) { | 2936 if (is_element) { |
| 2938 switch (GetElementsKind()) { | 2937 switch (GetElementsKind()) { |
| 2939 case FAST_ELEMENTS: | 2938 case FAST_ELEMENTS: |
| 2940 break; | 2939 break; |
| 2941 case PIXEL_ELEMENTS: | 2940 case PIXEL_ELEMENTS: |
| 2942 case EXTERNAL_BYTE_ELEMENTS: | 2941 case EXTERNAL_BYTE_ELEMENTS: |
| 2943 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2942 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2944 case EXTERNAL_SHORT_ELEMENTS: | 2943 case EXTERNAL_SHORT_ELEMENTS: |
| 2945 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2944 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| (...skipping 2190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5136 decoder->Reset(str.start(), str.length()); | 5135 decoder->Reset(str.start(), str.length()); |
| 5137 int i; | 5136 int i; |
| 5138 for (i = 0; i < slen && decoder->has_more(); i++) { | 5137 for (i = 0; i < slen && decoder->has_more(); i++) { |
| 5139 uc32 r = decoder->GetNext(); | 5138 uc32 r = decoder->GetNext(); |
| 5140 if (Get(i) != r) return false; | 5139 if (Get(i) != r) return false; |
| 5141 } | 5140 } |
| 5142 return i == slen && !decoder->has_more(); | 5141 return i == slen && !decoder->has_more(); |
| 5143 } | 5142 } |
| 5144 | 5143 |
| 5145 | 5144 |
| 5145 bool String::IsAsciiEqualTo(Vector<const char> str) { |
| 5146 int slen = length(); |
| 5147 if (str.length() != slen) return false; |
| 5148 for (int i = 0; i < slen; i++) { |
| 5149 if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
| 5150 } |
| 5151 return true; |
| 5152 } |
| 5153 |
| 5154 |
| 5155 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { |
| 5156 int slen = length(); |
| 5157 if (str.length() != slen) return false; |
| 5158 for (int i = 0; i < slen; i++) { |
| 5159 if (Get(i) != str[i]) return false; |
| 5160 } |
| 5161 return true; |
| 5162 } |
| 5163 |
| 5164 |
| 5146 template <typename schar> | 5165 template <typename schar> |
| 5147 static inline uint32_t HashSequentialString(const schar* chars, int length) { | 5166 static inline uint32_t HashSequentialString(const schar* chars, int length) { |
| 5148 StringHasher hasher(length); | 5167 StringHasher hasher(length); |
| 5149 if (!hasher.has_trivial_hash()) { | 5168 if (!hasher.has_trivial_hash()) { |
| 5150 int i; | 5169 int i; |
| 5151 for (i = 0; hasher.is_array_index() && (i < length); i++) { | 5170 for (i = 0; hasher.is_array_index() && (i < length); i++) { |
| 5152 hasher.AddCharacter(chars[i]); | 5171 hasher.AddCharacter(chars[i]); |
| 5153 } | 5172 } |
| 5154 for (; i < length; i++) { | 5173 for (; i < length; i++) { |
| 5155 hasher.AddCharacterNoIndex(chars[i]); | 5174 hasher.AddCharacterNoIndex(chars[i]); |
| (...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6768 // Handle [] on String objects. | 6787 // Handle [] on String objects. |
| 6769 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6788 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 6770 | 6789 |
| 6771 Object* pt = GetPrototype(); | 6790 Object* pt = GetPrototype(); |
| 6772 if (pt == Heap::null_value()) return false; | 6791 if (pt == Heap::null_value()) return false; |
| 6773 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6792 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 6774 } | 6793 } |
| 6775 | 6794 |
| 6776 | 6795 |
| 6777 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 6796 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
| 6778 Object* value) { | 6797 Object* value, |
| 6798 bool check_prototype) { |
| 6779 // Make sure that the top context does not change when doing | 6799 // Make sure that the top context does not change when doing |
| 6780 // callbacks or interceptor calls. | 6800 // callbacks or interceptor calls. |
| 6781 AssertNoContextChange ncc; | 6801 AssertNoContextChange ncc; |
| 6782 HandleScope scope; | 6802 HandleScope scope; |
| 6783 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6803 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 6784 Handle<JSObject> this_handle(this); | 6804 Handle<JSObject> this_handle(this); |
| 6785 Handle<Object> value_handle(value); | 6805 Handle<Object> value_handle(value); |
| 6786 if (!interceptor->setter()->IsUndefined()) { | 6806 if (!interceptor->setter()->IsUndefined()) { |
| 6787 v8::IndexedPropertySetter setter = | 6807 v8::IndexedPropertySetter setter = |
| 6788 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 6808 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
| 6789 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 6809 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 6790 CustomArguments args(interceptor->data(), this, this); | 6810 CustomArguments args(interceptor->data(), this, this); |
| 6791 v8::AccessorInfo info(args.end()); | 6811 v8::AccessorInfo info(args.end()); |
| 6792 v8::Handle<v8::Value> result; | 6812 v8::Handle<v8::Value> result; |
| 6793 { | 6813 { |
| 6794 // Leaving JavaScript. | 6814 // Leaving JavaScript. |
| 6795 VMState state(EXTERNAL); | 6815 VMState state(EXTERNAL); |
| 6796 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 6816 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
| 6797 } | 6817 } |
| 6798 RETURN_IF_SCHEDULED_EXCEPTION(); | 6818 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6799 if (!result.IsEmpty()) return *value_handle; | 6819 if (!result.IsEmpty()) return *value_handle; |
| 6800 } | 6820 } |
| 6801 MaybeObject* raw_result = | 6821 MaybeObject* raw_result = |
| 6802 this_handle->SetElementWithoutInterceptor(index, *value_handle); | 6822 this_handle->SetElementWithoutInterceptor(index, |
| 6823 *value_handle, |
| 6824 check_prototype); |
| 6803 RETURN_IF_SCHEDULED_EXCEPTION(); | 6825 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6804 return raw_result; | 6826 return raw_result; |
| 6805 } | 6827 } |
| 6806 | 6828 |
| 6807 | 6829 |
| 6808 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 6830 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 6809 Object* structure, | 6831 Object* structure, |
| 6810 uint32_t index, | 6832 uint32_t index, |
| 6811 Object* holder) { | 6833 Object* holder) { |
| 6812 ASSERT(!structure->IsProxy()); | 6834 ASSERT(!structure->IsProxy()); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6903 } | 6925 } |
| 6904 | 6926 |
| 6905 UNREACHABLE(); | 6927 UNREACHABLE(); |
| 6906 return NULL; | 6928 return NULL; |
| 6907 } | 6929 } |
| 6908 | 6930 |
| 6909 | 6931 |
| 6910 // Adding n elements in fast case is O(n*n). | 6932 // Adding n elements in fast case is O(n*n). |
| 6911 // Note: revisit design to have dual undefined values to capture absent | 6933 // Note: revisit design to have dual undefined values to capture absent |
| 6912 // elements. | 6934 // elements. |
| 6913 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) { | 6935 MaybeObject* JSObject::SetFastElement(uint32_t index, |
| 6936 Object* value, |
| 6937 bool check_prototype) { |
| 6914 ASSERT(HasFastElements()); | 6938 ASSERT(HasFastElements()); |
| 6915 | 6939 |
| 6916 Object* elms_obj; | 6940 Object* elms_obj; |
| 6917 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 6941 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 6918 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 6942 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 6919 } | 6943 } |
| 6920 FixedArray* elms = FixedArray::cast(elms_obj); | 6944 FixedArray* elms = FixedArray::cast(elms_obj); |
| 6921 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 6945 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 6922 | 6946 |
| 6923 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { | 6947 if (check_prototype && |
| 6924 if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 6948 (index >= elms_length || elms->get(index)->IsTheHole()) && |
| 6925 return value; | 6949 SetElementWithCallbackSetterInPrototypes(index, value)) { |
| 6926 } | 6950 return value; |
| 6927 } | 6951 } |
| 6928 | 6952 |
| 6953 |
| 6929 // Check whether there is extra space in fixed array.. | 6954 // Check whether there is extra space in fixed array.. |
| 6930 if (index < elms_length) { | 6955 if (index < elms_length) { |
| 6931 elms->set(index, value); | 6956 elms->set(index, value); |
| 6932 if (IsJSArray()) { | 6957 if (IsJSArray()) { |
| 6933 // Update the length of the array if needed. | 6958 // Update the length of the array if needed. |
| 6934 uint32_t array_length = 0; | 6959 uint32_t array_length = 0; |
| 6935 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 6960 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
| 6936 if (index >= array_length) { | 6961 if (index >= array_length) { |
| 6937 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 6962 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
| 6938 } | 6963 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 6956 return value; | 6981 return value; |
| 6957 } | 6982 } |
| 6958 } | 6983 } |
| 6959 | 6984 |
| 6960 // Otherwise default to slow case. | 6985 // Otherwise default to slow case. |
| 6961 Object* obj; | 6986 Object* obj; |
| 6962 { MaybeObject* maybe_obj = NormalizeElements(); | 6987 { MaybeObject* maybe_obj = NormalizeElements(); |
| 6963 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6988 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6964 } | 6989 } |
| 6965 ASSERT(HasDictionaryElements()); | 6990 ASSERT(HasDictionaryElements()); |
| 6966 return SetElement(index, value); | 6991 return SetElement(index, value, check_prototype); |
| 6967 } | 6992 } |
| 6968 | 6993 |
| 6969 | 6994 |
| 6970 MaybeObject* JSObject::SetElement(uint32_t index, Object* value) { | 6995 MaybeObject* JSObject::SetElement(uint32_t index, |
| 6996 Object* value, |
| 6997 bool check_prototype) { |
| 6971 // Check access rights if needed. | 6998 // Check access rights if needed. |
| 6972 if (IsAccessCheckNeeded() && | 6999 if (IsAccessCheckNeeded() && |
| 6973 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7000 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 6974 HandleScope scope; | 7001 HandleScope scope; |
| 6975 Handle<Object> value_handle(value); | 7002 Handle<Object> value_handle(value); |
| 6976 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7003 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 6977 return *value_handle; | 7004 return *value_handle; |
| 6978 } | 7005 } |
| 6979 | 7006 |
| 6980 if (IsJSGlobalProxy()) { | 7007 if (IsJSGlobalProxy()) { |
| 6981 Object* proto = GetPrototype(); | 7008 Object* proto = GetPrototype(); |
| 6982 if (proto->IsNull()) return value; | 7009 if (proto->IsNull()) return value; |
| 6983 ASSERT(proto->IsJSGlobalObject()); | 7010 ASSERT(proto->IsJSGlobalObject()); |
| 6984 return JSObject::cast(proto)->SetElement(index, value); | 7011 return JSObject::cast(proto)->SetElement(index, value, check_prototype); |
| 6985 } | 7012 } |
| 6986 | 7013 |
| 6987 // Check for lookup interceptor | 7014 // Check for lookup interceptor |
| 6988 if (HasIndexedInterceptor()) { | 7015 if (HasIndexedInterceptor()) { |
| 6989 return SetElementWithInterceptor(index, value); | 7016 return SetElementWithInterceptor(index, value, check_prototype); |
| 6990 } | 7017 } |
| 6991 | 7018 |
| 6992 return SetElementWithoutInterceptor(index, value); | 7019 return SetElementWithoutInterceptor(index, value, check_prototype); |
| 6993 } | 7020 } |
| 6994 | 7021 |
| 6995 | 7022 |
| 6996 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7023 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 6997 Object* value) { | 7024 Object* value, |
| 7025 bool check_prototype) { |
| 6998 switch (GetElementsKind()) { | 7026 switch (GetElementsKind()) { |
| 6999 case FAST_ELEMENTS: | 7027 case FAST_ELEMENTS: |
| 7000 // Fast case. | 7028 // Fast case. |
| 7001 return SetFastElement(index, value); | 7029 return SetFastElement(index, value, check_prototype); |
| 7002 case PIXEL_ELEMENTS: { | 7030 case PIXEL_ELEMENTS: { |
| 7003 PixelArray* pixels = PixelArray::cast(elements()); | 7031 PixelArray* pixels = PixelArray::cast(elements()); |
| 7004 return pixels->SetValue(index, value); | 7032 return pixels->SetValue(index, value); |
| 7005 } | 7033 } |
| 7006 case EXTERNAL_BYTE_ELEMENTS: { | 7034 case EXTERNAL_BYTE_ELEMENTS: { |
| 7007 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7035 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| 7008 return array->SetValue(index, value); | 7036 return array->SetValue(index, value); |
| 7009 } | 7037 } |
| 7010 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7038 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 7011 ExternalUnsignedByteArray* array = | 7039 ExternalUnsignedByteArray* array = |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7044 Object* element = dictionary->ValueAt(entry); | 7072 Object* element = dictionary->ValueAt(entry); |
| 7045 PropertyDetails details = dictionary->DetailsAt(entry); | 7073 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7046 if (details.type() == CALLBACKS) { | 7074 if (details.type() == CALLBACKS) { |
| 7047 return SetElementWithCallback(element, index, value, this); | 7075 return SetElementWithCallback(element, index, value, this); |
| 7048 } else { | 7076 } else { |
| 7049 dictionary->UpdateMaxNumberKey(index); | 7077 dictionary->UpdateMaxNumberKey(index); |
| 7050 dictionary->ValueAtPut(entry, value); | 7078 dictionary->ValueAtPut(entry, value); |
| 7051 } | 7079 } |
| 7052 } else { | 7080 } else { |
| 7053 // Index not already used. Look for an accessor in the prototype chain. | 7081 // Index not already used. Look for an accessor in the prototype chain. |
| 7054 if (!IsJSArray()) { | 7082 if (check_prototype && |
| 7055 if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 7083 SetElementWithCallbackSetterInPrototypes(index, value)) { |
| 7056 return value; | 7084 return value; |
| 7057 } | |
| 7058 } | 7085 } |
| 7059 // When we set the is_extensible flag to false we always force | 7086 // When we set the is_extensible flag to false we always force |
| 7060 // the element into dictionary mode (and force them to stay there). | 7087 // the element into dictionary mode (and force them to stay there). |
| 7061 if (!map()->is_extensible()) { | 7088 if (!map()->is_extensible()) { |
| 7062 Handle<Object> number(Factory::NewNumberFromUint(index)); | 7089 Handle<Object> number(Factory::NewNumberFromUint(index)); |
| 7063 Handle<String> index_string(Factory::NumberToString(number)); | 7090 Handle<String> index_string(Factory::NumberToString(number)); |
| 7064 Handle<Object> args[1] = { index_string }; | 7091 Handle<Object> args[1] = { index_string }; |
| 7065 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 7092 return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
| 7066 HandleVector(args, 1))); | 7093 HandleVector(args, 1))); |
| 7067 } | 7094 } |
| (...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8079 if (hash_field_ == 0) Hash(); | 8106 if (hash_field_ == 0) Hash(); |
| 8080 return Heap::AllocateSymbol(string_, chars_, hash_field_); | 8107 return Heap::AllocateSymbol(string_, chars_, hash_field_); |
| 8081 } | 8108 } |
| 8082 | 8109 |
| 8083 Vector<const char> string_; | 8110 Vector<const char> string_; |
| 8084 uint32_t hash_field_; | 8111 uint32_t hash_field_; |
| 8085 int chars_; // Caches the number of characters when computing the hash code. | 8112 int chars_; // Caches the number of characters when computing the hash code. |
| 8086 }; | 8113 }; |
| 8087 | 8114 |
| 8088 | 8115 |
| 8116 template <typename Char> |
| 8117 class SequentialSymbolKey : public HashTableKey { |
| 8118 public: |
| 8119 explicit SequentialSymbolKey(Vector<const Char> string) |
| 8120 : string_(string), hash_field_(0) { } |
| 8121 |
| 8122 uint32_t Hash() { |
| 8123 StringHasher hasher(string_.length()); |
| 8124 |
| 8125 // Very long strings have a trivial hash that doesn't inspect the |
| 8126 // string contents. |
| 8127 if (hasher.has_trivial_hash()) { |
| 8128 hash_field_ = hasher.GetHashField(); |
| 8129 } else { |
| 8130 int i = 0; |
| 8131 // Do the iterative array index computation as long as there is a |
| 8132 // chance this is an array index. |
| 8133 while (i < string_.length() && hasher.is_array_index()) { |
| 8134 hasher.AddCharacter(static_cast<uc32>(string_[i])); |
| 8135 i++; |
| 8136 } |
| 8137 |
| 8138 // Process the remaining characters without updating the array |
| 8139 // index. |
| 8140 while (i < string_.length()) { |
| 8141 hasher.AddCharacterNoIndex(static_cast<uc32>(string_[i])); |
| 8142 i++; |
| 8143 } |
| 8144 hash_field_ = hasher.GetHashField(); |
| 8145 } |
| 8146 |
| 8147 uint32_t result = hash_field_ >> String::kHashShift; |
| 8148 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 8149 return result; |
| 8150 } |
| 8151 |
| 8152 |
| 8153 uint32_t HashForObject(Object* other) { |
| 8154 return String::cast(other)->Hash(); |
| 8155 } |
| 8156 |
| 8157 Vector<const Char> string_; |
| 8158 uint32_t hash_field_; |
| 8159 }; |
| 8160 |
| 8161 |
| 8162 |
| 8163 class AsciiSymbolKey : public SequentialSymbolKey<char> { |
| 8164 public: |
| 8165 explicit AsciiSymbolKey(Vector<const char> str) |
| 8166 : SequentialSymbolKey<char>(str) { } |
| 8167 |
| 8168 bool IsMatch(Object* string) { |
| 8169 return String::cast(string)->IsAsciiEqualTo(string_); |
| 8170 } |
| 8171 |
| 8172 MaybeObject* AsObject() { |
| 8173 if (hash_field_ == 0) Hash(); |
| 8174 return Heap::AllocateAsciiSymbol(string_, hash_field_); |
| 8175 } |
| 8176 }; |
| 8177 |
| 8178 |
| 8179 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
| 8180 public: |
| 8181 explicit TwoByteSymbolKey(Vector<const uc16> str) |
| 8182 : SequentialSymbolKey<uc16>(str) { } |
| 8183 |
| 8184 bool IsMatch(Object* string) { |
| 8185 return String::cast(string)->IsTwoByteEqualTo(string_); |
| 8186 } |
| 8187 |
| 8188 MaybeObject* AsObject() { |
| 8189 if (hash_field_ == 0) Hash(); |
| 8190 return Heap::AllocateTwoByteSymbol(string_, hash_field_); |
| 8191 } |
| 8192 }; |
| 8193 |
| 8194 |
| 8089 // SymbolKey carries a string/symbol object as key. | 8195 // SymbolKey carries a string/symbol object as key. |
| 8090 class SymbolKey : public HashTableKey { | 8196 class SymbolKey : public HashTableKey { |
| 8091 public: | 8197 public: |
| 8092 explicit SymbolKey(String* string) : string_(string) { } | 8198 explicit SymbolKey(String* string) : string_(string) { } |
| 8093 | 8199 |
| 8094 bool IsMatch(Object* string) { | 8200 bool IsMatch(Object* string) { |
| 8095 return String::cast(string)->Equals(string_); | 8201 return String::cast(string)->Equals(string_); |
| 8096 } | 8202 } |
| 8097 | 8203 |
| 8098 uint32_t Hash() { return string_->Hash(); } | 8204 uint32_t Hash() { return string_->Hash(); } |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8823 } | 8929 } |
| 8824 } | 8930 } |
| 8825 | 8931 |
| 8826 | 8932 |
| 8827 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 8933 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { |
| 8828 Utf8SymbolKey key(str); | 8934 Utf8SymbolKey key(str); |
| 8829 return LookupKey(&key, s); | 8935 return LookupKey(&key, s); |
| 8830 } | 8936 } |
| 8831 | 8937 |
| 8832 | 8938 |
| 8939 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
| 8940 Object** s) { |
| 8941 AsciiSymbolKey key(str); |
| 8942 return LookupKey(&key, s); |
| 8943 } |
| 8944 |
| 8945 |
| 8946 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
| 8947 Object** s) { |
| 8948 TwoByteSymbolKey key(str); |
| 8949 return LookupKey(&key, s); |
| 8950 } |
| 8951 |
| 8833 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 8952 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
| 8834 int entry = FindEntry(key); | 8953 int entry = FindEntry(key); |
| 8835 | 8954 |
| 8836 // Symbol already in table. | 8955 // Symbol already in table. |
| 8837 if (entry != kNotFound) { | 8956 if (entry != kNotFound) { |
| 8838 *s = KeyAt(entry); | 8957 *s = KeyAt(entry); |
| 8839 return this; | 8958 return this; |
| 8840 } | 8959 } |
| 8841 | 8960 |
| 8842 // Adding new symbol. Grow table if needed. | 8961 // Adding new symbol. Grow table if needed. |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9747 if (break_point_objects()->IsUndefined()) return 0; | 9866 if (break_point_objects()->IsUndefined()) return 0; |
| 9748 // Single beak point. | 9867 // Single beak point. |
| 9749 if (!break_point_objects()->IsFixedArray()) return 1; | 9868 if (!break_point_objects()->IsFixedArray()) return 1; |
| 9750 // Multiple break points. | 9869 // Multiple break points. |
| 9751 return FixedArray::cast(break_point_objects())->length(); | 9870 return FixedArray::cast(break_point_objects())->length(); |
| 9752 } | 9871 } |
| 9753 #endif | 9872 #endif |
| 9754 | 9873 |
| 9755 | 9874 |
| 9756 } } // namespace v8::internal | 9875 } } // namespace v8::internal |
| OLD | NEW |