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

Side by Side Diff: src/objects.cc

Issue 50016: Allow hidden properties and implement GetIdentityHash (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.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-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 3218 matching lines...) Expand 10 before | Expand all | Expand 10 after
3229 for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) { 3229 for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) {
3230 if (GetKey(mid)->Equals(name) && !is_null_descriptor(mid)) return mid; 3230 if (GetKey(mid)->Equals(name) && !is_null_descriptor(mid)) return mid;
3231 } 3231 }
3232 break; 3232 break;
3233 } 3233 }
3234 return kNotFound; 3234 return kNotFound;
3235 } 3235 }
3236 3236
3237 3237
3238 int DescriptorArray::LinearSearch(String* name, int len) { 3238 int DescriptorArray::LinearSearch(String* name, int len) {
3239 uint32_t hash = name->Hash();
3239 for (int number = 0; number < len; number++) { 3240 for (int number = 0; number < len; number++) {
3240 if (name->Equals(GetKey(number)) && !is_null_descriptor(number)) { 3241 String* entry = GetKey(number);
3242 if ((entry->Hash() == hash) &&
3243 name->Equals(entry) &&
3244 !is_null_descriptor(number)) {
3241 return number; 3245 return number;
3242 } 3246 }
3243 } 3247 }
3244 return kNotFound; 3248 return kNotFound;
3245 } 3249 }
3246 3250
3247 3251
3248 #ifdef DEBUG 3252 #ifdef DEBUG
3249 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { 3253 bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
3250 if (IsEmpty()) return other->IsEmpty(); 3254 if (IsEmpty()) return other->IsEmpty();
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after
4274 int i; 4278 int i;
4275 for (i = 0; i < slen && decoder->has_more(); i++) { 4279 for (i = 0; i < slen && decoder->has_more(); i++) {
4276 uc32 r = decoder->GetNext(); 4280 uc32 r = decoder->GetNext();
4277 if (Get(i) != r) return false; 4281 if (Get(i) != r) return false;
4278 } 4282 }
4279 return i == slen && !decoder->has_more(); 4283 return i == slen && !decoder->has_more();
4280 } 4284 }
4281 4285
4282 4286
4283 uint32_t String::ComputeAndSetHash() { 4287 uint32_t String::ComputeAndSetHash() {
4284 // Should only be call if hash code has not yet been computed. 4288 // Should only be called if hash code has not yet been computed.
4285 ASSERT(!(length_field() & kHashComputedMask)); 4289 ASSERT(!(length_field() & kHashComputedMask));
4286 4290
4287 // Compute the hash code. 4291 // Compute the hash code.
4288 StringInputBuffer buffer(this); 4292 StringInputBuffer buffer(this);
4289 uint32_t field = ComputeLengthAndHashField(&buffer, length()); 4293 uint32_t field = ComputeLengthAndHashField(&buffer, length());
4290 4294
4291 // Store the hash code in the object. 4295 // Store the hash code in the object.
4292 set_length_field(field); 4296 set_length_field(field);
4293 4297
4294 // Check the hash code is there. 4298 // Check the hash code is there.
4295 ASSERT(length_field() & kHashComputedMask); 4299 ASSERT(length_field() & kHashComputedMask);
4296 return field >> kHashShift; 4300 uint32_t result = field >> kHashShift;
4301 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
4302 return result;
4297 } 4303 }
4298 4304
4299 4305
4300 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer, 4306 bool String::ComputeArrayIndex(unibrow::CharacterStream* buffer,
4301 uint32_t* index, 4307 uint32_t* index,
4302 int length) { 4308 int length) {
4303 if (length == 0 || length > kMaxArrayIndexSize) return false; 4309 if (length == 0 || length > kMaxArrayIndexSize) return false;
4304 uc32 ch = buffer->GetNext(); 4310 uc32 ch = buffer->GetNext();
4305 4311
4306 // If the string begins with a '0' character, it must only consist 4312 // If the string begins with a '0' character, it must only consist
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
5164 Smi::cast(JSArray::cast(this)->length())->value()) : 5170 Smi::cast(JSArray::cast(this)->length())->value()) :
5165 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 5171 static_cast<uint32_t>(FixedArray::cast(elements())->length());
5166 return (index < length) && 5172 return (index < length) &&
5167 !FixedArray::cast(elements())->get(index)->IsTheHole(); 5173 !FixedArray::cast(elements())->get(index)->IsTheHole();
5168 } else { 5174 } else {
5169 return element_dictionary()->FindNumberEntry(index) != -1; 5175 return element_dictionary()->FindNumberEntry(index) != -1;
5170 } 5176 }
5171 } 5177 }
5172 5178
5173 5179
5180 Object* JSObject::GetHiddenProperties(bool create_if_needed) {
5181 String* key = Heap::hidden_symbol();
5182 if (this->HasFastProperties()) {
5183 // If the object has fast properties, check whether the first slot in the
5184 // descriptor array matches the hidden symbol. Since the hidden symbols
5185 // hash code is zero it will always occupy the first entry if present.
5186 DescriptorArray* descriptors = this->map()->instance_descriptors();
5187 if (descriptors->number_of_descriptors() > 0) {
5188 if (descriptors->GetKey(0) == key) {
5189 #ifdef DEBUG
5190 PropertyDetails details(descriptors->GetDetails(0));
5191 ASSERT(details.type() == FIELD);
5192 #endif // DEBUG
5193 Object* value = descriptors->GetValue(0);
5194 return FastPropertyAt(Descriptor::IndexFromValue(value));
5195 }
5196 }
5197 }
5198
5199 // Only attempt to find the hidden properties in the local object and not
5200 // in the prototype chain.
5201 if (!this->HasLocalProperty(key)) {
5202 // Hidden properties object not found. Allocate a new hidden properties
5203 // object if requested. Otherwise return the undefined value.
5204 if (create_if_needed) {
5205 Object* obj = Heap::AllocateJSObject(
5206 Top::context()->global_context()->object_function());
5207 if (obj->IsFailure()) {
5208 return obj;
5209 }
5210 return this->SetProperty(key, obj, DONT_ENUM);
5211 } else {
5212 return Heap::undefined_value();
5213 }
5214 }
5215 return this->GetProperty(key);
5216 }
5217
5218
5174 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { 5219 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
5175 // Check access rights if needed. 5220 // Check access rights if needed.
5176 if (IsAccessCheckNeeded() && 5221 if (IsAccessCheckNeeded() &&
5177 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 5222 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
5178 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 5223 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS);
5179 return false; 5224 return false;
5180 } 5225 }
5181 5226
5182 // Check for lookup interceptor 5227 // Check for lookup interceptor
5183 if (HasIndexedInterceptor()) { 5228 if (HasIndexedInterceptor()) {
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
6058 return static_cast<uint32_t>(obj->Number()); 6103 return static_cast<uint32_t>(obj->Number());
6059 } 6104 }
6060 6105
6061 uint32_t number_; 6106 uint32_t number_;
6062 }; 6107 };
6063 6108
6064 6109
6065 // StringKey simply carries a string object as key. 6110 // StringKey simply carries a string object as key.
6066 class StringKey : public HashTableKey { 6111 class StringKey : public HashTableKey {
6067 public: 6112 public:
6068 explicit StringKey(String* string) : string_(string) { } 6113 explicit StringKey(String* string) :
6114 string_(string),
6115 hash_(StringHash(string)) { }
6069 6116
6070 bool IsMatch(Object* string) { 6117 bool IsMatch(Object* string) {
6118 // We know that all entries in a hash table had their hash keys created.
6119 // Use that knowledge to have fast failure.
6120 if (hash_ != StringHash(string)) {
6121 return false;
6122 }
6071 return string_->Equals(String::cast(string)); 6123 return string_->Equals(String::cast(string));
6072 } 6124 }
6073 6125
6074 uint32_t Hash() { return StringHash(string_); } 6126 uint32_t Hash() { return hash_; }
6075 6127
6076 HashFunction GetHashFunction() { return StringHash; } 6128 HashFunction GetHashFunction() { return StringHash; }
6077 6129
6078 Object* GetObject() { return string_; } 6130 Object* GetObject() { return string_; }
6079 6131
6080 static uint32_t StringHash(Object* obj) { 6132 static uint32_t StringHash(Object* obj) {
6081 return String::cast(obj)->Hash(); 6133 return String::cast(obj)->Hash();
6082 } 6134 }
6083 6135
6084 bool IsStringKey() { return true; } 6136 bool IsStringKey() { return true; }
6085 6137
6086 String* string_; 6138 String* string_;
6139 uint32_t hash_;
6087 }; 6140 };
6088 6141
6089 6142
6090 // StringSharedKeys are used as keys in the eval cache. 6143 // StringSharedKeys are used as keys in the eval cache.
6091 class StringSharedKey : public HashTableKey { 6144 class StringSharedKey : public HashTableKey {
6092 public: 6145 public:
6093 StringSharedKey(String* source, SharedFunctionInfo* shared) 6146 StringSharedKey(String* source, SharedFunctionInfo* shared)
6094 : source_(source), shared_(shared) { } 6147 : source_(source), shared_(shared) { }
6095 6148
6096 bool IsMatch(Object* other) { 6149 bool IsMatch(Object* other) {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
6203 HashFunction GetHashFunction() { 6256 HashFunction GetHashFunction() {
6204 return StringHash; 6257 return StringHash;
6205 } 6258 }
6206 6259
6207 uint32_t Hash() { 6260 uint32_t Hash() {
6208 if (length_field_ != 0) return length_field_ >> String::kHashShift; 6261 if (length_field_ != 0) return length_field_ >> String::kHashShift;
6209 unibrow::Utf8InputBuffer<> buffer(string_.start(), 6262 unibrow::Utf8InputBuffer<> buffer(string_.start(),
6210 static_cast<unsigned>(string_.length())); 6263 static_cast<unsigned>(string_.length()));
6211 chars_ = buffer.Length(); 6264 chars_ = buffer.Length();
6212 length_field_ = String::ComputeLengthAndHashField(&buffer, chars_); 6265 length_field_ = String::ComputeLengthAndHashField(&buffer, chars_);
6213 return length_field_ >> String::kHashShift; 6266 uint32_t result = length_field_ >> String::kHashShift;
6267 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
6268 return result;
6214 } 6269 }
6215 6270
6216 Object* GetObject() { 6271 Object* GetObject() {
6217 if (length_field_ == 0) Hash(); 6272 if (length_field_ == 0) Hash();
6218 return Heap::AllocateSymbol(string_, chars_, length_field_); 6273 return Heap::AllocateSymbol(string_, chars_, length_field_);
6219 } 6274 }
6220 6275
6221 static uint32_t StringHash(Object* obj) { 6276 static uint32_t StringHash(Object* obj) {
6222 return String::cast(obj)->Hash(); 6277 return String::cast(obj)->Hash();
6223 } 6278 }
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after
7364 // No break point. 7419 // No break point.
7365 if (break_point_objects()->IsUndefined()) return 0; 7420 if (break_point_objects()->IsUndefined()) return 0;
7366 // Single beak point. 7421 // Single beak point.
7367 if (!break_point_objects()->IsFixedArray()) return 1; 7422 if (!break_point_objects()->IsFixedArray()) return 1;
7368 // Multiple break points. 7423 // Multiple break points.
7369 return FixedArray::cast(break_point_objects())->length(); 7424 return FixedArray::cast(break_point_objects())->length();
7370 } 7425 }
7371 7426
7372 7427
7373 } } // namespace v8::internal 7428 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698