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

Side by Side Diff: src/objects.cc

Issue 11035053: Rollback trunk to bleeding_edge revision 12525 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 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-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 value = result->holder()->FastPropertyAt(result->GetFieldIndex()); 644 value = result->holder()->FastPropertyAt(result->GetFieldIndex());
645 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 645 ASSERT(!value->IsTheHole() || result->IsReadOnly());
646 return value->IsTheHole() ? heap->undefined_value() : value; 646 return value->IsTheHole() ? heap->undefined_value() : value;
647 case CONSTANT_FUNCTION: 647 case CONSTANT_FUNCTION:
648 return result->GetConstantFunction(); 648 return result->GetConstantFunction();
649 case CALLBACKS: 649 case CALLBACKS:
650 return result->holder()->GetPropertyWithCallback( 650 return result->holder()->GetPropertyWithCallback(
651 receiver, result->GetCallbackObject(), name); 651 receiver, result->GetCallbackObject(), name);
652 case HANDLER: 652 case HANDLER:
653 return result->proxy()->GetPropertyWithHandler(receiver, name); 653 return result->proxy()->GetPropertyWithHandler(receiver, name);
654 case INTERCEPTOR: 654 case INTERCEPTOR: {
655 JSObject* recvr = JSObject::cast(receiver);
655 return result->holder()->GetPropertyWithInterceptor( 656 return result->holder()->GetPropertyWithInterceptor(
656 receiver, name, attributes); 657 recvr, name, attributes);
658 }
657 case TRANSITION: 659 case TRANSITION:
658 case NONEXISTENT: 660 case NONEXISTENT:
659 UNREACHABLE(); 661 UNREACHABLE();
660 break; 662 break;
661 } 663 }
662 UNREACHABLE(); 664 UNREACHABLE();
663 return NULL; 665 return NULL;
664 } 666 }
665 667
666 668
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 return value; 1685 return value;
1684 } else { 1686 } else {
1685 Handle<Object> args[1] = {Handle<String>(name)}; 1687 Handle<Object> args[1] = {Handle<String>(name)};
1686 return heap->isolate()->Throw( 1688 return heap->isolate()->Throw(
1687 *FACTORY->NewTypeError("object_not_extensible", 1689 *FACTORY->NewTypeError("object_not_extensible",
1688 HandleVector(args, 1))); 1690 HandleVector(args, 1)));
1689 } 1691 }
1690 } 1692 }
1691 if (HasFastProperties()) { 1693 if (HasFastProperties()) {
1692 // Ensure the descriptor array does not get too big. 1694 // Ensure the descriptor array does not get too big.
1693 if (map_of_this->NumberOfOwnDescriptors() < 1695 if (map_of_this->instance_descriptors()->number_of_descriptors() <
1694 DescriptorArray::kMaxNumberOfDescriptors) { 1696 DescriptorArray::kMaxNumberOfDescriptors) {
1695 if (value->IsJSFunction()) { 1697 if (value->IsJSFunction()) {
1696 return AddConstantFunctionProperty(name, 1698 return AddConstantFunctionProperty(name,
1697 JSFunction::cast(value), 1699 JSFunction::cast(value),
1698 attributes); 1700 attributes);
1699 } else { 1701 } else {
1700 return AddFastProperty(name, value, attributes, store_mode); 1702 return AddFastProperty(name, value, attributes, store_mode);
1701 } 1703 }
1702 } else { 1704 } else {
1703 // Normalize the object to prevent very large instance descriptors. 1705 // Normalize the object to prevent very large instance descriptors.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 // descriptor array is returned to the smaller maps by installing a reduced 1777 // descriptor array is returned to the smaller maps by installing a reduced
1776 // copy of the descriptor array in the old_map. 1778 // copy of the descriptor array in the old_map.
1777 1779
1778 // This phase is executed before creating the new map since it requires 1780 // This phase is executed before creating the new map since it requires
1779 // allocation that may fail. 1781 // allocation that may fail.
1780 if (!old_target->StoresOwnDescriptors()) { 1782 if (!old_target->StoresOwnDescriptors()) {
1781 DescriptorArray* old_descriptors = old_map->instance_descriptors(); 1783 DescriptorArray* old_descriptors = old_map->instance_descriptors();
1782 1784
1783 old_target->SetBackPointer(GetHeap()->undefined_value()); 1785 old_target->SetBackPointer(GetHeap()->undefined_value());
1784 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); 1786 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors);
1785 // Reset the backpointer before returning failure, otherwise the map ends up 1787 if (maybe_failure->IsFailure()) return maybe_failure;
1786 // with an undefined backpointer and no descriptors, losing its own
1787 // descriptors. Setting the backpointer always succeeds.
1788 old_target->SetBackPointer(old_map); 1788 old_target->SetBackPointer(old_map);
1789 if (maybe_failure->IsFailure()) return maybe_failure;
1790 1789
1791 old_map->set_owns_descriptors(true); 1790 old_map->set_owns_descriptors(true);
1792 } 1791 }
1793 1792
1794 MaybeObject* maybe_result = 1793 MaybeObject* maybe_result =
1795 ConvertDescriptorToField(name, new_value, attributes); 1794 ConvertDescriptorToField(name, new_value, attributes);
1796 if (!maybe_result->To(&result)) return maybe_result; 1795 if (!maybe_result->To(&result)) return maybe_result;
1797 1796
1798 if (!HasFastProperties()) return result; 1797 if (!HasFastProperties()) return result;
1799 1798
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 return heap->the_hole_value(); 2168 return heap->the_hole_value();
2170 } 2169 }
2171 2170
2172 2171
2173 enum RightTrimMode { FROM_GC, FROM_MUTATOR }; 2172 enum RightTrimMode { FROM_GC, FROM_MUTATOR };
2174 2173
2175 2174
2176 static void ZapEndOfFixedArray(Address new_end, int to_trim) { 2175 static void ZapEndOfFixedArray(Address new_end, int to_trim) {
2177 // If we are doing a big trim in old space then we zap the space. 2176 // If we are doing a big trim in old space then we zap the space.
2178 Object** zap = reinterpret_cast<Object**>(new_end); 2177 Object** zap = reinterpret_cast<Object**>(new_end);
2179 zap++; // Header of filler must be at least one word so skip that.
2180 for (int i = 1; i < to_trim; i++) { 2178 for (int i = 1; i < to_trim; i++) {
2181 *zap++ = Smi::FromInt(0); 2179 *zap++ = Smi::FromInt(0);
2182 } 2180 }
2183 } 2181 }
2184 2182
2185
2186 template<RightTrimMode trim_mode> 2183 template<RightTrimMode trim_mode>
2187 static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) { 2184 static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
2188 ASSERT(elms->map() != HEAP->fixed_cow_array_map()); 2185 ASSERT(elms->map() != HEAP->fixed_cow_array_map());
2189 // For now this trick is only applied to fixed arrays in new and paged space. 2186 // For now this trick is only applied to fixed arrays in new and paged space.
2190 ASSERT(!HEAP->lo_space()->Contains(elms)); 2187 ASSERT(!HEAP->lo_space()->Contains(elms));
2191 2188
2192 const int len = elms->length(); 2189 const int len = elms->length();
2193 2190
2194 ASSERT(to_trim < len); 2191 ASSERT(to_trim < len);
2195 2192
(...skipping 20 matching lines...) Expand all
2216 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) { 2213 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
2217 if (trim_mode == FROM_GC) { 2214 if (trim_mode == FROM_GC) {
2218 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta); 2215 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
2219 } else { 2216 } else {
2220 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta); 2217 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2221 } 2218 }
2222 } 2219 }
2223 } 2220 }
2224 2221
2225 2222
2226 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 2223 void Map::CopyAppendCallbackDescriptors(Handle<Map> map,
2227 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 2224 Handle<Object> descriptors) {
2228 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
2229 int number_of_descriptors = descriptors->number_of_descriptors();
2230 Isolate* isolate = map->GetIsolate();
2231 Handle<DescriptorArray> new_descriptors =
2232 isolate->factory()->NewDescriptorArray(number_of_descriptors, slack);
2233 DescriptorArray::WhitenessWitness witness(*new_descriptors);
2234
2235 for (int i = 0; i < number_of_descriptors; ++i) {
2236 new_descriptors->CopyFrom(i, *descriptors, i, witness);
2237 }
2238
2239 Map::SetDescriptors(map, new_descriptors);
2240 }
2241
2242
2243 void Map::AppendCallbackDescriptors(Handle<Map> map,
2244 Handle<Object> descriptors) {
2245 Isolate* isolate = map->GetIsolate(); 2225 Isolate* isolate = map->GetIsolate();
2246 Handle<DescriptorArray> array(map->instance_descriptors()); 2226 Handle<DescriptorArray> array(map->instance_descriptors());
2247 NeanderArray callbacks(descriptors); 2227 v8::NeanderArray callbacks(descriptors);
2248 int nof_callbacks = callbacks.length(); 2228 int nof_callbacks = callbacks.length();
2249 2229 int descriptor_count = array->number_of_descriptors();
2250 ASSERT(array->NumberOfSlackDescriptors() >= nof_callbacks); 2230 ASSERT(descriptor_count == map->NumberOfOwnDescriptors());
2251 2231
2252 // Ensure the keys are symbols before writing them into the instance 2232 // Ensure the keys are symbols before writing them into the instance
2253 // descriptor. Since it may cause a GC, it has to be done before we 2233 // descriptor. Since it may cause a GC, it has to be done before we
2254 // temporarily put the heap in an invalid state while appending descriptors. 2234 // temporarily put the heap in an invalid state while appending descriptors.
2255 for (int i = 0; i < nof_callbacks; ++i) { 2235 for (int i = 0; i < nof_callbacks; ++i) {
2256 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i))); 2236 Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks.get(i)));
2257 Handle<String> key = 2237 Handle<String> key =
2258 isolate->factory()->SymbolFromString( 2238 isolate->factory()->SymbolFromString(
2259 Handle<String>(String::cast(entry->name()))); 2239 Handle<String>(String::cast(entry->name())));
2260 entry->set_name(*key); 2240 entry->set_name(*key);
2261 } 2241 }
2262 2242
2263 int nof = map->NumberOfOwnDescriptors(); 2243 Handle<DescriptorArray> result =
2244 isolate->factory()->NewDescriptorArray(descriptor_count + nof_callbacks);
2245
2246 // Ensure that marking will not progress and change color of objects.
2247 DescriptorArray::WhitenessWitness witness(*result);
2248
2249 // Copy the descriptors from the array.
2250 for (int i = 0; i < descriptor_count; i++) {
2251 result->CopyFrom(i, *array, i, witness);
2252 }
2253
2254 // After this point the GC is not allowed to run anymore until the map is in a
2255 // consistent state again, i.e., all the descriptors are appended and the
2256 // descriptor array is trimmed to the right size.
2257 Map::SetDescriptors(map, result);
2264 2258
2265 // Fill in new callback descriptors. Process the callbacks from 2259 // Fill in new callback descriptors. Process the callbacks from
2266 // back to front so that the last callback with a given name takes 2260 // back to front so that the last callback with a given name takes
2267 // precedence over previously added callbacks with that name. 2261 // precedence over previously added callbacks with that name.
2262 int nof = descriptor_count;
2268 for (int i = nof_callbacks - 1; i >= 0; i--) { 2263 for (int i = nof_callbacks - 1; i >= 0; i--) {
2269 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i)); 2264 AccessorInfo* entry = AccessorInfo::cast(callbacks.get(i));
2270 String* key = String::cast(entry->name()); 2265 String* key = String::cast(entry->name());
2271 // Check if a descriptor with this name already exists before writing. 2266 // Check if a descriptor with this name already exists before writing.
2272 if (array->Search(key, nof) == DescriptorArray::kNotFound) { 2267 if (result->Search(key, nof) == DescriptorArray::kNotFound) {
2273 CallbacksDescriptor desc(key, entry, entry->property_attributes()); 2268 CallbacksDescriptor desc(key, entry, entry->property_attributes());
2274 array->Append(&desc); 2269 map->AppendDescriptor(&desc, witness);
2275 nof += 1; 2270 nof += 1;
2276 } 2271 }
2277 } 2272 }
2278 2273
2279 map->SetNumberOfOwnDescriptors(nof); 2274 ASSERT(nof == map->NumberOfOwnDescriptors());
2275
2276 // Reinstall the original descriptor array if no new elements were added.
2277 if (nof == descriptor_count) {
2278 Map::SetDescriptors(map, array);
2279 return;
2280 }
2281
2282 // If duplicates were detected, trim the descriptor array to the right size.
2283 int new_array_size = DescriptorArray::LengthFor(nof);
2284 if (new_array_size < result->length()) {
2285 RightTrimFixedArray<FROM_MUTATOR>(
2286 isolate->heap(), *result, result->length() - new_array_size);
2287 }
2280 } 2288 }
2281 2289
2282 2290
2283 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) { 2291 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) {
2284 ASSERT(!map.is_null()); 2292 ASSERT(!map.is_null());
2285 for (int i = 0; i < maps->length(); ++i) { 2293 for (int i = 0; i < maps->length(); ++i) {
2286 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true; 2294 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true;
2287 } 2295 }
2288 return false; 2296 return false;
2289 } 2297 }
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
3333 3341
3334 // The global object is always normalized. 3342 // The global object is always normalized.
3335 ASSERT(!IsGlobalObject()); 3343 ASSERT(!IsGlobalObject());
3336 // JSGlobalProxy must never be normalized 3344 // JSGlobalProxy must never be normalized
3337 ASSERT(!IsJSGlobalProxy()); 3345 ASSERT(!IsJSGlobalProxy());
3338 3346
3339 Map* map_of_this = map(); 3347 Map* map_of_this = map();
3340 3348
3341 // Allocate new content. 3349 // Allocate new content.
3342 int real_size = map_of_this->NumberOfOwnDescriptors(); 3350 int real_size = map_of_this->NumberOfOwnDescriptors();
3343 int property_count = real_size; 3351 int property_count =
3352 map_of_this->NumberOfDescribedProperties(OWN_DESCRIPTORS);
3344 if (expected_additional_properties > 0) { 3353 if (expected_additional_properties > 0) {
3345 property_count += expected_additional_properties; 3354 property_count += expected_additional_properties;
3346 } else { 3355 } else {
3347 property_count += 2; // Make space for two more properties. 3356 property_count += 2; // Make space for two more properties.
3348 } 3357 }
3349 StringDictionary* dictionary; 3358 StringDictionary* dictionary;
3350 MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count); 3359 MaybeObject* maybe_dictionary = StringDictionary::Allocate(property_count);
3351 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 3360 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
3352 3361
3353 DescriptorArray* descs = map_of_this->instance_descriptors(); 3362 DescriptorArray* descs = map_of_this->instance_descriptors();
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after
4997 // descriptors in the descriptor array. 5006 // descriptors in the descriptor array.
4998 ASSERT(NumberOfOwnDescriptors() == 5007 ASSERT(NumberOfOwnDescriptors() ==
4999 instance_descriptors()->number_of_descriptors()); 5008 instance_descriptors()->number_of_descriptors());
5000 Map* result; 5009 Map* result;
5001 MaybeObject* maybe_result = CopyDropDescriptors(); 5010 MaybeObject* maybe_result = CopyDropDescriptors();
5002 if (!maybe_result->To(&result)) return maybe_result; 5011 if (!maybe_result->To(&result)) return maybe_result;
5003 5012
5004 String* name = descriptor->GetKey(); 5013 String* name = descriptor->GetKey();
5005 5014
5006 TransitionArray* transitions; 5015 TransitionArray* transitions;
5007 MaybeObject* maybe_transitions = 5016 MaybeObject* maybe_transitions = AddTransition(name, result);
5008 AddTransition(name, result, SIMPLE_TRANSITION);
5009 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 5017 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
5010 5018
5011 DescriptorArray* descriptors = instance_descriptors(); 5019 DescriptorArray* descriptors = instance_descriptors();
5012 int old_size = descriptors->number_of_descriptors(); 5020 int old_size = descriptors->number_of_descriptors();
5013 5021
5014 DescriptorArray* new_descriptors; 5022 DescriptorArray* new_descriptors;
5023 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
5024 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5025 DescriptorArray::WhitenessWitness witness(new_descriptors);
5015 5026
5016 if (descriptors->NumberOfSlackDescriptors() > 0) { 5027 for (int i = 0; i < old_size; ++i) {
5017 new_descriptors = descriptors; 5028 new_descriptors->CopyFrom(i, descriptors, i, witness);
5018 new_descriptors->Append(descriptor); 5029 }
5019 } else { 5030 new_descriptors->Append(descriptor, witness, old_size);
5020 // Descriptor arrays grow by 50%.
5021 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
5022 old_size, old_size < 4 ? 1 : old_size / 2);
5023 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5024 5031
5025 DescriptorArray::WhitenessWitness witness(new_descriptors); 5032 // If the source descriptors had an enum cache we copy it. This ensures that
5026 5033 // the maps to which we push the new descriptor array back can rely on a
5027 // Copy the descriptors, inserting a descriptor. 5034 // cache always being available once it is set. If the map has more
5028 for (int i = 0; i < old_size; ++i) { 5035 // enumerated descriptors than available in the original cache, the cache
5029 new_descriptors->CopyFrom(i, descriptors, i, witness); 5036 // will be lazily replaced by the extended cache when needed.
5030 } 5037 if (descriptors->HasEnumCache()) {
5031 5038 new_descriptors->CopyEnumCacheFrom(descriptors);
5032 new_descriptors->Append(descriptor, witness);
5033
5034 // If the source descriptors had an enum cache we copy it. This ensures that
5035 // the maps to which we push the new descriptor array back can rely on a
5036 // cache always being available once it is set. If the map has more
5037 // enumerated descriptors than available in the original cache, the cache
5038 // will be lazily replaced by the extended cache when needed.
5039 if (descriptors->HasEnumCache()) {
5040 new_descriptors->CopyEnumCacheFrom(descriptors);
5041 }
5042 } 5039 }
5043 5040
5044 transitions->set_descriptors(new_descriptors); 5041 transitions->set_descriptors(new_descriptors);
5045
5046 set_transitions(transitions); 5042 set_transitions(transitions);
5047 result->SetBackPointer(this); 5043 result->SetBackPointer(this);
5048 set_owns_descriptors(false); 5044 set_owns_descriptors(false);
5049 5045
5050 result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors()); 5046 result->SetNumberOfOwnDescriptors(new_descriptors->number_of_descriptors());
5051 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); 5047 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
5052 5048
5053 return result; 5049 return result;
5054 } 5050 }
5055 5051
5056 5052
5057 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 5053 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
5058 String* name, 5054 String* name,
5059 TransitionFlag flag, 5055 TransitionFlag flag) {
5060 int descriptor_index) {
5061 ASSERT(descriptors->IsSortedNoDuplicates()); 5056 ASSERT(descriptors->IsSortedNoDuplicates());
5062 5057
5063 Map* result; 5058 Map* result;
5064 MaybeObject* maybe_result = CopyDropDescriptors(); 5059 MaybeObject* maybe_result = CopyDropDescriptors();
5065 if (!maybe_result->To(&result)) return maybe_result; 5060 if (!maybe_result->To(&result)) return maybe_result;
5066 5061
5067 // Unless we are creating a map with no descriptors and no back pointer, we 5062 // Unless we are creating a map with no descriptors and no back pointer, we
5068 // insert the descriptor array locally. 5063 // insert the descriptor array locally.
5069 if (!descriptors->IsEmpty()) { 5064 if (!descriptors->IsEmpty()) {
5070 MaybeObject* maybe_failure = result->SetDescriptors(descriptors); 5065 MaybeObject* maybe_failure = result->SetDescriptors(descriptors);
5071 if (maybe_failure->IsFailure()) return maybe_failure; 5066 if (maybe_failure->IsFailure()) return maybe_failure;
5072 result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors()); 5067 result->SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
5073 } 5068 }
5074 5069
5075 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 5070 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
5076 TransitionArray* transitions; 5071 TransitionArray* transitions;
5077 SimpleTransitionFlag simple_flag = 5072 MaybeObject* maybe_transitions = AddTransition(name, result);
5078 (descriptor_index == descriptors->number_of_descriptors() - 1)
5079 ? SIMPLE_TRANSITION
5080 : FULL_TRANSITION;
5081 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
5082 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 5073 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
5083 5074
5084 if (descriptors->IsEmpty()) { 5075 if (descriptors->IsEmpty()) {
5085 if (owns_descriptors()) { 5076 if (owns_descriptors()) {
5086 // If the copied map has no added fields, and the parent map owns its 5077 // If the copied map has no added fields, and the parent map owns its
5087 // descriptors, those descriptors have to be empty. In that case, 5078 // descriptors, those descriptors have to be empty. In that case,
5088 // transfer ownership of the descriptors to the new child. 5079 // transfer ownership of the descriptors to the new child.
5089 ASSERT(instance_descriptors()->IsEmpty()); 5080 ASSERT(instance_descriptors()->IsEmpty());
5090 set_owns_descriptors(false); 5081 set_owns_descriptors(false);
5091 } else { 5082 } else {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 JSFunction* ctor = JSFunction::cast(constructor()); 5167 JSFunction* ctor = JSFunction::cast(constructor());
5177 Map* map = ctor->initial_map(); 5168 Map* map = ctor->initial_map();
5178 DescriptorArray* descriptors = map->instance_descriptors(); 5169 DescriptorArray* descriptors = map->instance_descriptors();
5179 5170
5180 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 5171 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
5181 DescriptorArray* new_descriptors; 5172 DescriptorArray* new_descriptors;
5182 MaybeObject* maybe_descriptors = 5173 MaybeObject* maybe_descriptors =
5183 descriptors->CopyUpTo(number_of_own_descriptors); 5174 descriptors->CopyUpTo(number_of_own_descriptors);
5184 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 5175 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5185 5176
5186 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); 5177 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION);
5187 } 5178 }
5188 5179
5189 5180
5190 MaybeObject* Map::Copy() { 5181 MaybeObject* Map::Copy() {
5191 DescriptorArray* descriptors = instance_descriptors(); 5182 DescriptorArray* descriptors = instance_descriptors();
5192 DescriptorArray* new_descriptors; 5183 DescriptorArray* new_descriptors;
5193 int number_of_own_descriptors = NumberOfOwnDescriptors(); 5184 int number_of_own_descriptors = NumberOfOwnDescriptors();
5194 MaybeObject* maybe_descriptors = 5185 MaybeObject* maybe_descriptors =
5195 descriptors->CopyUpTo(number_of_own_descriptors); 5186 descriptors->CopyUpTo(number_of_own_descriptors);
5196 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 5187 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5197 5188
5198 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0); 5189 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION);
5199 } 5190 }
5200 5191
5201 5192
5202 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, 5193 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
5203 TransitionFlag flag) { 5194 TransitionFlag flag) {
5204 DescriptorArray* descriptors = instance_descriptors(); 5195 DescriptorArray* descriptors = instance_descriptors();
5205 5196
5206 // Ensure the key is a symbol. 5197 // Ensure the key is a symbol.
5207 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); 5198 MaybeObject* maybe_failure = descriptor->KeyToSymbol();
5208 if (maybe_failure->IsFailure()) return maybe_failure; 5199 if (maybe_failure->IsFailure()) return maybe_failure;
5209 5200
5210 int old_size = NumberOfOwnDescriptors(); 5201 int old_size = NumberOfOwnDescriptors();
5211 int new_size = old_size + 1; 5202 int new_size = old_size + 1;
5212 descriptor->SetEnumerationIndex(new_size); 5203 descriptor->SetEnumerationIndex(new_size);
5213 5204
5214 if (flag == INSERT_TRANSITION && 5205 if (flag == INSERT_TRANSITION &&
5215 owns_descriptors() && 5206 owns_descriptors() &&
5216 CanHaveMoreTransitions()) { 5207 CanHaveMoreTransitions()) {
5217 return ShareDescriptor(descriptor); 5208 return ShareDescriptor(descriptor);
5218 } 5209 }
5219 5210
5220 DescriptorArray* new_descriptors; 5211 DescriptorArray* new_descriptors;
5221 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size, 1); 5212 MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
5222 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 5213 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5223 5214
5224 DescriptorArray::WhitenessWitness witness(new_descriptors); 5215 DescriptorArray::WhitenessWitness witness(new_descriptors);
5225 5216
5226 // Copy the descriptors, inserting a descriptor. 5217 // Copy the descriptors, inserting a descriptor.
5227 for (int i = 0; i < old_size; ++i) { 5218 for (int i = 0; i < old_size; ++i) {
5228 new_descriptors->CopyFrom(i, descriptors, i, witness); 5219 new_descriptors->CopyFrom(i, descriptors, i, witness);
5229 } 5220 }
5230 5221
5231 if (old_size != descriptors->number_of_descriptors()) { 5222 new_descriptors->Set(old_size, descriptor, witness);
5232 new_descriptors->SetNumberOfDescriptors(new_size); 5223 new_descriptors->Sort();
5233 new_descriptors->Set(old_size, descriptor, witness);
5234 new_descriptors->Sort();
5235 } else {
5236 new_descriptors->Append(descriptor, witness);
5237 }
5238 5224
5239 String* key = descriptor->GetKey(); 5225 return CopyReplaceDescriptors(new_descriptors, descriptor->GetKey(), flag);
5240 int insertion_index = new_descriptors->number_of_descriptors() - 1;
5241
5242 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
5243 } 5226 }
5244 5227
5245 5228
5246 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, 5229 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
5247 TransitionFlag flag) { 5230 TransitionFlag flag) {
5248 DescriptorArray* old_descriptors = instance_descriptors(); 5231 DescriptorArray* old_descriptors = instance_descriptors();
5249 5232
5250 // Ensure the key is a symbol. 5233 // Ensure the key is a symbol.
5251 MaybeObject* maybe_result = descriptor->KeyToSymbol(); 5234 MaybeObject* maybe_result = descriptor->KeyToSymbol();
5252 if (maybe_result->IsFailure()) return maybe_result; 5235 if (maybe_result->IsFailure()) return maybe_result;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
5308 if (i == insertion_index) { 5291 if (i == insertion_index) {
5309 new_descriptors->Set(i, descriptor, witness); 5292 new_descriptors->Set(i, descriptor, witness);
5310 } else { 5293 } else {
5311 new_descriptors->CopyFrom(i, descriptors, i, witness); 5294 new_descriptors->CopyFrom(i, descriptors, i, witness);
5312 } 5295 }
5313 } 5296 }
5314 5297
5315 // Re-sort if descriptors were removed. 5298 // Re-sort if descriptors were removed.
5316 if (new_size != descriptors->length()) new_descriptors->Sort(); 5299 if (new_size != descriptors->length()) new_descriptors->Sort();
5317 5300
5318 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index); 5301 return CopyReplaceDescriptors(new_descriptors, key, flag);
5319 } 5302 }
5320 5303
5321 5304
5322 void Map::UpdateCodeCache(Handle<Map> map, 5305 void Map::UpdateCodeCache(Handle<Map> map,
5323 Handle<String> name, 5306 Handle<String> name,
5324 Handle<Code> code) { 5307 Handle<Code> code) {
5325 Isolate* isolate = map->GetIsolate(); 5308 Isolate* isolate = map->GetIsolate();
5326 CALL_HEAP_FUNCTION_VOID(isolate, 5309 CALL_HEAP_FUNCTION_VOID(isolate,
5327 map->UpdateCodeCache(*name, *code)); 5310 map->UpdateCodeCache(*name, *code));
5328 } 5311 }
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
6083 bool FixedArray::IsEqualTo(FixedArray* other) { 6066 bool FixedArray::IsEqualTo(FixedArray* other) {
6084 if (length() != other->length()) return false; 6067 if (length() != other->length()) return false;
6085 for (int i = 0 ; i < length(); ++i) { 6068 for (int i = 0 ; i < length(); ++i) {
6086 if (get(i) != other->get(i)) return false; 6069 if (get(i) != other->get(i)) return false;
6087 } 6070 }
6088 return true; 6071 return true;
6089 } 6072 }
6090 #endif 6073 #endif
6091 6074
6092 6075
6093 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors, int slack) { 6076 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
6094 Heap* heap = Isolate::Current()->heap(); 6077 Heap* heap = Isolate::Current()->heap();
6095 // Do not use DescriptorArray::cast on incomplete object. 6078 // Do not use DescriptorArray::cast on incomplete object.
6096 int size = number_of_descriptors + slack;
6097 if (size == 0) return heap->empty_descriptor_array();
6098 FixedArray* result; 6079 FixedArray* result;
6080 if (number_of_descriptors == 0) return heap->empty_descriptor_array();
6099 // Allocate the array of keys. 6081 // Allocate the array of keys.
6100 MaybeObject* maybe_array = heap->AllocateFixedArray(LengthFor(size)); 6082 MaybeObject* maybe_array =
6083 heap->AllocateFixedArray(LengthFor(number_of_descriptors));
6101 if (!maybe_array->To(&result)) return maybe_array; 6084 if (!maybe_array->To(&result)) return maybe_array;
6102 6085
6103 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors));
6104 result->set(kEnumCacheIndex, Smi::FromInt(0)); 6086 result->set(kEnumCacheIndex, Smi::FromInt(0));
6105 return result; 6087 return result;
6106 } 6088 }
6107 6089
6108 6090
6109 void DescriptorArray::ClearEnumCache() { 6091 void DescriptorArray::ClearEnumCache() {
6110 set(kEnumCacheIndex, Smi::FromInt(0)); 6092 set(kEnumCacheIndex, Smi::FromInt(0));
6111 } 6093 }
6112 6094
6113 6095
6114 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 6096 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
6115 FixedArray* new_cache, 6097 FixedArray* new_cache,
6116 Object* new_index_cache) { 6098 Object* new_index_cache) {
6117 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 6099 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
6118 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); 6100 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
6119 if (HasEnumCache()) { 6101 if (HasEnumCache()) {
6120 ASSERT(new_cache->length() > GetEnumCache()->length()); 6102 ASSERT(new_cache->length() > FixedArray::cast(GetEnumCache())->length());
6121 FixedArray::cast(get(kEnumCacheIndex))-> 6103 FixedArray::cast(get(kEnumCacheIndex))->
6122 set(kEnumCacheBridgeCacheIndex, new_cache); 6104 set(kEnumCacheBridgeCacheIndex, new_cache);
6123 FixedArray::cast(get(kEnumCacheIndex))-> 6105 FixedArray::cast(get(kEnumCacheIndex))->
6124 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); 6106 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
6125 } else { 6107 } else {
6126 ASSERT(!IsEmpty()); 6108 ASSERT(!IsEmpty());
6127 FixedArray::cast(bridge_storage)-> 6109 FixedArray::cast(bridge_storage)->
6128 set(kEnumCacheBridgeCacheIndex, new_cache); 6110 set(kEnumCacheBridgeCacheIndex, new_cache);
6129 FixedArray::cast(bridge_storage)-> 6111 FixedArray::cast(bridge_storage)->
6130 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); 6112 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after
7383 7365
7384 void StringHasher::AddSurrogatePairNoIndex(uc32 c) { 7366 void StringHasher::AddSurrogatePairNoIndex(uc32 c) {
7385 uint16_t lead = unibrow::Utf16::LeadSurrogate(c); 7367 uint16_t lead = unibrow::Utf16::LeadSurrogate(c);
7386 AddCharacterNoIndex(lead); 7368 AddCharacterNoIndex(lead);
7387 uint16_t trail = unibrow::Utf16::TrailSurrogate(c); 7369 uint16_t trail = unibrow::Utf16::TrailSurrogate(c);
7388 AddCharacterNoIndex(trail); 7370 AddCharacterNoIndex(trail);
7389 } 7371 }
7390 7372
7391 7373
7392 uint32_t StringHasher::GetHashField() { 7374 uint32_t StringHasher::GetHashField() {
7375 ASSERT(is_valid());
7393 if (length_ <= String::kMaxHashCalcLength) { 7376 if (length_ <= String::kMaxHashCalcLength) {
7394 if (is_array_index()) { 7377 if (is_array_index()) {
7395 return MakeArrayIndexHash(array_index(), length_); 7378 return MakeArrayIndexHash(array_index(), length_);
7396 } 7379 }
7397 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask; 7380 return (GetHash() << String::kHashShift) | String::kIsNotArrayIndexMask;
7398 } else { 7381 } else {
7399 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; 7382 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask;
7400 } 7383 }
7401 } 7384 }
7402 7385
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7446 7429
7447 // Clear a possible back pointer in case the transition leads to a dead map. 7430 // Clear a possible back pointer in case the transition leads to a dead map.
7448 // Return true in case a back pointer has been cleared and false otherwise. 7431 // Return true in case a back pointer has been cleared and false otherwise.
7449 static bool ClearBackPointer(Heap* heap, Map* target) { 7432 static bool ClearBackPointer(Heap* heap, Map* target) {
7450 if (Marking::MarkBitFrom(target).Get()) return false; 7433 if (Marking::MarkBitFrom(target).Get()) return false;
7451 target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER); 7434 target->SetBackPointer(heap->undefined_value(), SKIP_WRITE_BARRIER);
7452 return true; 7435 return true;
7453 } 7436 }
7454 7437
7455 7438
7456 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
7457 int live_enum = map->EnumLength();
7458 if (live_enum == Map::kInvalidEnumCache) {
7459 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
7460 }
7461 if (live_enum == 0) return descriptors->ClearEnumCache();
7462
7463 FixedArray* enum_cache = descriptors->GetEnumCache();
7464
7465 int to_trim = enum_cache->length() - live_enum;
7466 if (to_trim <= 0) return;
7467 RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim);
7468
7469 if (!descriptors->HasEnumIndicesCache()) return;
7470 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
7471 RightTrimFixedArray<FROM_GC>(heap, enum_indices_cache, to_trim);
7472 }
7473
7474
7475 static void TrimDescriptorArray(Heap* heap,
7476 Map* map,
7477 DescriptorArray* descriptors,
7478 int number_of_own_descriptors) {
7479 int number_of_descriptors = descriptors->number_of_descriptors();
7480 int to_trim = number_of_descriptors - number_of_own_descriptors;
7481 if (to_trim <= 0) return;
7482
7483 // Maximally keep 50% of unused descriptors.
7484 int keep = Min(to_trim, number_of_own_descriptors / 2);
7485 for (int i = number_of_own_descriptors;
7486 i < number_of_own_descriptors + keep;
7487 ++i) {
7488 descriptors->EraseDescriptor(heap, i);
7489 }
7490
7491 if (to_trim > keep) {
7492 RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep);
7493 }
7494 descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
7495
7496 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
7497 descriptors->Sort();
7498 }
7499
7500
7501 // TODO(mstarzinger): This method should be moved into MarkCompactCollector, 7439 // TODO(mstarzinger): This method should be moved into MarkCompactCollector,
7502 // because it cannot be called from outside the GC and we already have methods 7440 // because it cannot be called from outside the GC and we already have methods
7503 // depending on the transitions layout in the GC anyways. 7441 // depending on the transitions layout in the GC anyways.
7504 void Map::ClearNonLiveTransitions(Heap* heap) { 7442 void Map::ClearNonLiveTransitions(Heap* heap) {
7505 // If there are no transitions to be cleared, return. 7443 // If there are no transitions to be cleared, return.
7506 // TODO(verwaest) Should be an assert, otherwise back pointers are not 7444 // TODO(verwaest) Should be an assert, otherwise back pointers are not
7507 // properly cleared. 7445 // properly cleared.
7508 if (!HasTransitionArray()) return; 7446 if (!HasTransitionArray()) return;
7509 7447
7510 TransitionArray* t = transitions(); 7448 TransitionArray* t = transitions();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
7549 // If there are no transitions to be cleared, return. 7487 // If there are no transitions to be cleared, return.
7550 // TODO(verwaest) Should be an assert, otherwise back pointers are not 7488 // TODO(verwaest) Should be an assert, otherwise back pointers are not
7551 // properly cleared. 7489 // properly cleared.
7552 if (transition_index == t->number_of_transitions()) return; 7490 if (transition_index == t->number_of_transitions()) return;
7553 } 7491 }
7554 7492
7555 int number_of_own_descriptors = NumberOfOwnDescriptors(); 7493 int number_of_own_descriptors = NumberOfOwnDescriptors();
7556 7494
7557 if (descriptors_owner_died) { 7495 if (descriptors_owner_died) {
7558 if (number_of_own_descriptors > 0) { 7496 if (number_of_own_descriptors > 0) {
7559 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); 7497 int number_of_descriptors = descriptors->number_of_descriptors();
7498 int to_trim = number_of_descriptors - number_of_own_descriptors;
7499 if (to_trim > 0) {
7500 RightTrimFixedArray<FROM_GC>(
7501 heap, descriptors, to_trim * DescriptorArray::kDescriptorSize);
7502 if (descriptors->HasEnumCache()) {
7503 int live_enum =
7504 NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
7505 if (live_enum == 0) {
7506 descriptors->ClearEnumCache();
7507 } else {
7508 FixedArray* enum_cache =
7509 FixedArray::cast(descriptors->GetEnumCache());
7510 to_trim = enum_cache->length() - live_enum;
7511 if (to_trim > 0) {
7512 RightTrimFixedArray<FROM_GC>(
7513 heap, FixedArray::cast(descriptors->GetEnumCache()), to_trim);
7514 }
7515 }
7516 }
7517 descriptors->Sort();
7518 }
7560 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); 7519 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
7561 } else { 7520 } else {
7562 t->set_descriptors(heap->empty_descriptor_array()); 7521 t->set_descriptors(heap->empty_descriptor_array());
7563 } 7522 }
7564 set_owns_descriptors(true); 7523 set_owns_descriptors(true);
7565 } 7524 }
7566 7525
7567 // If the final transition array does not contain any live transitions, remove 7526 // If the final transition array does not contain any live transitions, remove
7568 // the transition array from the map. 7527 // the transition array from the map.
7569 if (transition_index == 0 && 7528 if (transition_index == 0 &&
7570 !t->HasElementsTransition() && 7529 !t->HasElementsTransition() &&
7571 !t->HasPrototypeTransitions() && 7530 !t->HasPrototypeTransitions() &&
7572 number_of_own_descriptors == 0) { 7531 number_of_own_descriptors == 0) {
7573 ASSERT(owns_descriptors()); 7532 ASSERT(owns_descriptors());
7574 return ClearTransitions(heap); 7533 return ClearTransitions(heap);
7575 } 7534 }
7576 7535
7577 int trim = t->number_of_transitions() - transition_index; 7536 int trim = t->number_of_transitions() - transition_index;
7578 if (trim > 0) { 7537 if (trim > 0) {
7579 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() 7538 RightTrimFixedArray<FROM_GC>(
7580 ? trim : trim * TransitionArray::kTransitionSize); 7539 heap, t, trim * TransitionArray::kTransitionSize);
7581 } 7540 }
7582 } 7541 }
7583 7542
7584 7543
7585 int Map::Hash() { 7544 int Map::Hash() {
7586 // For performance reasons we only hash the 3 most variable fields of a map: 7545 // For performance reasons we only hash the 3 most variable fields of a map:
7587 // constructor, prototype and bit_field2. 7546 // constructor, prototype and bit_field2.
7588 7547
7589 // Shift away the tag. 7548 // Shift away the tag.
7590 int hash = (static_cast<uint32_t>( 7549 int hash = (static_cast<uint32_t>(
(...skipping 2926 matching lines...) Expand 10 before | Expand all | Expand 10 after
10517 ASSERT(map()->has_indexed_interceptor()); 10476 ASSERT(map()->has_indexed_interceptor());
10518 JSFunction* constructor = JSFunction::cast(map()->constructor()); 10477 JSFunction* constructor = JSFunction::cast(map()->constructor());
10519 ASSERT(constructor->shared()->IsApiFunction()); 10478 ASSERT(constructor->shared()->IsApiFunction());
10520 Object* result = 10479 Object* result =
10521 constructor->shared()->get_api_func_data()->indexed_property_handler(); 10480 constructor->shared()->get_api_func_data()->indexed_property_handler();
10522 return InterceptorInfo::cast(result); 10481 return InterceptorInfo::cast(result);
10523 } 10482 }
10524 10483
10525 10484
10526 MaybeObject* JSObject::GetPropertyPostInterceptor( 10485 MaybeObject* JSObject::GetPropertyPostInterceptor(
10527 Object* receiver, 10486 JSReceiver* receiver,
10528 String* name, 10487 String* name,
10529 PropertyAttributes* attributes) { 10488 PropertyAttributes* attributes) {
10530 // Check local property in holder, ignore interceptor. 10489 // Check local property in holder, ignore interceptor.
10531 LookupResult result(GetIsolate()); 10490 LookupResult result(GetIsolate());
10532 LocalLookupRealNamedProperty(name, &result); 10491 LocalLookupRealNamedProperty(name, &result);
10533 if (result.IsFound()) { 10492 if (result.IsFound()) {
10534 return GetProperty(receiver, &result, name, attributes); 10493 return GetProperty(receiver, &result, name, attributes);
10535 } 10494 }
10536 // Continue searching via the prototype chain. 10495 // Continue searching via the prototype chain.
10537 Object* pt = GetPrototype(); 10496 Object* pt = GetPrototype();
10538 *attributes = ABSENT; 10497 *attributes = ABSENT;
10539 if (pt->IsNull()) return GetHeap()->undefined_value(); 10498 if (pt->IsNull()) return GetHeap()->undefined_value();
10540 return pt->GetPropertyWithReceiver(receiver, name, attributes); 10499 return pt->GetPropertyWithReceiver(receiver, name, attributes);
10541 } 10500 }
10542 10501
10543 10502
10544 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( 10503 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
10545 Object* receiver, 10504 JSReceiver* receiver,
10546 String* name, 10505 String* name,
10547 PropertyAttributes* attributes) { 10506 PropertyAttributes* attributes) {
10548 // Check local property in holder, ignore interceptor. 10507 // Check local property in holder, ignore interceptor.
10549 LookupResult result(GetIsolate()); 10508 LookupResult result(GetIsolate());
10550 LocalLookupRealNamedProperty(name, &result); 10509 LocalLookupRealNamedProperty(name, &result);
10551 if (result.IsFound()) { 10510 if (result.IsFound()) {
10552 return GetProperty(receiver, &result, name, attributes); 10511 return GetProperty(receiver, &result, name, attributes);
10553 } 10512 }
10554 return GetHeap()->undefined_value(); 10513 return GetHeap()->undefined_value();
10555 } 10514 }
10556 10515
10557 10516
10558 MaybeObject* JSObject::GetPropertyWithInterceptor( 10517 MaybeObject* JSObject::GetPropertyWithInterceptor(
10559 Object* receiver, 10518 JSReceiver* receiver,
10560 String* name, 10519 String* name,
10561 PropertyAttributes* attributes) { 10520 PropertyAttributes* attributes) {
10562 Isolate* isolate = GetIsolate(); 10521 Isolate* isolate = GetIsolate();
10563 InterceptorInfo* interceptor = GetNamedInterceptor(); 10522 InterceptorInfo* interceptor = GetNamedInterceptor();
10564 HandleScope scope(isolate); 10523 HandleScope scope(isolate);
10565 Handle<Object> receiver_handle(receiver); 10524 Handle<JSReceiver> receiver_handle(receiver);
10566 Handle<JSObject> holder_handle(this); 10525 Handle<JSObject> holder_handle(this);
10567 Handle<String> name_handle(name); 10526 Handle<String> name_handle(name);
10568 10527
10569 if (!interceptor->getter()->IsUndefined()) { 10528 if (!interceptor->getter()->IsUndefined()) {
10570 v8::NamedPropertyGetter getter = 10529 v8::NamedPropertyGetter getter =
10571 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); 10530 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
10572 LOG(isolate, 10531 LOG(isolate,
10573 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); 10532 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name));
10574 CustomArguments args(isolate, interceptor->data(), receiver, this); 10533 CustomArguments args(isolate, interceptor->data(), receiver, this);
10575 v8::AccessorInfo info(args.end()); 10534 v8::AccessorInfo info(args.end());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
10687 } 10646 }
10688 } 10647 }
10689 10648
10690 LookupResult result(isolate); 10649 LookupResult result(isolate);
10691 LocalLookupRealNamedProperty(key, &result); 10650 LocalLookupRealNamedProperty(key, &result);
10692 return result.IsPropertyCallbacks(); 10651 return result.IsPropertyCallbacks();
10693 } 10652 }
10694 10653
10695 10654
10696 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 10655 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
10697 if (HasFastProperties()) { 10656 return HasFastProperties() ?
10698 Map* map = this->map(); 10657 map()->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter) :
10699 if (filter == NONE) return map->NumberOfOwnDescriptors(); 10658 property_dictionary()->NumberOfElementsFilterAttributes(filter);
10700 if (filter == DONT_ENUM) {
10701 int result = map->EnumLength();
10702 if (result != Map::kInvalidEnumCache) return result;
10703 }
10704 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
10705 }
10706 return property_dictionary()->NumberOfElementsFilterAttributes(filter);
10707 } 10659 }
10708 10660
10709 10661
10710 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { 10662 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) {
10711 Object* temp = get(i); 10663 Object* temp = get(i);
10712 set(i, get(j)); 10664 set(i, get(j));
10713 set(j, temp); 10665 set(j, temp);
10714 if (this != numbers) { 10666 if (this != numbers) {
10715 temp = numbers->get(i); 10667 temp = numbers->get(i);
10716 numbers->set(i, Smi::cast(numbers->get(j))); 10668 numbers->set(i, Smi::cast(numbers->get(j)));
(...skipping 2833 matching lines...) Expand 10 before | Expand all | Expand 10 after
13550 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13502 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13551 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13503 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13552 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13504 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13553 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13505 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13554 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13506 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13555 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13507 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13556 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13508 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13557 } 13509 }
13558 13510
13559 } } // namespace v8::internal 13511 } } // 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