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

Side by Side Diff: src/objects.cc

Issue 15681004: Revert "Make Object.freeze fast" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 4489 matching lines...) Expand 10 before | Expand all | Expand 10 after
4500 4500
4501 4501
4502 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { 4502 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
4503 if (HasFastProperties()) return this; 4503 if (HasFastProperties()) return this;
4504 ASSERT(!IsGlobalObject()); 4504 ASSERT(!IsGlobalObject());
4505 return property_dictionary()-> 4505 return property_dictionary()->
4506 TransformPropertiesToFastFor(this, unused_property_fields); 4506 TransformPropertiesToFastFor(this, unused_property_fields);
4507 } 4507 }
4508 4508
4509 4509
4510 static MUST_USE_RESULT MaybeObject* CopyFastElementsToDictionary(
4511 Isolate* isolate,
4512 FixedArrayBase* array,
4513 int length,
4514 SeededNumberDictionary* dictionary) {
4515 Heap* heap = isolate->heap();
4516 bool has_double_elements = array->IsFixedDoubleArray();
4517 for (int i = 0; i < length; i++) {
4518 Object* value = NULL;
4519 if (has_double_elements) {
4520 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
4521 if (double_array->is_the_hole(i)) {
4522 value = isolate->heap()->the_hole_value();
4523 } else {
4524 // Objects must be allocated in the old object space, since the
4525 // overall number of HeapNumbers needed for the conversion might
4526 // exceed the capacity of new space, and we would fail repeatedly
4527 // trying to convert the FixedDoubleArray.
4528 MaybeObject* maybe_value_object =
4529 heap->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
4530 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
4531 }
4532 } else {
4533 value = FixedArray::cast(array)->get(i);
4534 }
4535 if (!value->IsTheHole()) {
4536 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
4537 MaybeObject* maybe_result =
4538 dictionary->AddNumberEntry(i, value, details);
4539 if (!maybe_result->To(&dictionary)) return maybe_result;
4540 }
4541 }
4542 return dictionary;
4543 }
4544
4545
4546 Handle<SeededNumberDictionary> JSObject::NormalizeElements( 4510 Handle<SeededNumberDictionary> JSObject::NormalizeElements(
4547 Handle<JSObject> object) { 4511 Handle<JSObject> object) {
4548 CALL_HEAP_FUNCTION(object->GetIsolate(), 4512 CALL_HEAP_FUNCTION(object->GetIsolate(),
4549 object->NormalizeElements(), 4513 object->NormalizeElements(),
4550 SeededNumberDictionary); 4514 SeededNumberDictionary);
4551 } 4515 }
4552 4516
4553 4517
4554 MaybeObject* JSObject::NormalizeElements() { 4518 MaybeObject* JSObject::NormalizeElements() {
4555 ASSERT(!HasExternalArrayElements()); 4519 ASSERT(!HasExternalArrayElements());
(...skipping 11 matching lines...) Expand all
4567 ASSERT(HasFastSmiOrObjectElements() || 4531 ASSERT(HasFastSmiOrObjectElements() ||
4568 HasFastDoubleElements() || 4532 HasFastDoubleElements() ||
4569 HasFastArgumentsElements()); 4533 HasFastArgumentsElements());
4570 // Compute the effective length and allocate a new backing store. 4534 // Compute the effective length and allocate a new backing store.
4571 int length = IsJSArray() 4535 int length = IsJSArray()
4572 ? Smi::cast(JSArray::cast(this)->length())->value() 4536 ? Smi::cast(JSArray::cast(this)->length())->value()
4573 : array->length(); 4537 : array->length();
4574 int old_capacity = 0; 4538 int old_capacity = 0;
4575 int used_elements = 0; 4539 int used_elements = 0;
4576 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 4540 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
4577 SeededNumberDictionary* dictionary; 4541 SeededNumberDictionary* dictionary = NULL;
4578 MaybeObject* maybe_dictionary = 4542 { Object* object;
4579 SeededNumberDictionary::Allocate(GetHeap(), used_elements); 4543 MaybeObject* maybe =
4580 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 4544 SeededNumberDictionary::Allocate(GetHeap(), used_elements);
4545 if (!maybe->ToObject(&object)) return maybe;
4546 dictionary = SeededNumberDictionary::cast(object);
4547 }
4581 4548
4582 maybe_dictionary = CopyFastElementsToDictionary( 4549 // Copy the elements to the new backing store.
4583 GetIsolate(), array, length, dictionary); 4550 bool has_double_elements = array->IsFixedDoubleArray();
4584 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 4551 for (int i = 0; i < length; i++) {
4552 Object* value = NULL;
4553 if (has_double_elements) {
4554 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
4555 if (double_array->is_the_hole(i)) {
4556 value = GetIsolate()->heap()->the_hole_value();
4557 } else {
4558 // Objects must be allocated in the old object space, since the
4559 // overall number of HeapNumbers needed for the conversion might
4560 // exceed the capacity of new space, and we would fail repeatedly
4561 // trying to convert the FixedDoubleArray.
4562 MaybeObject* maybe_value_object =
4563 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
4564 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
4565 }
4566 } else {
4567 ASSERT(old_map->has_fast_smi_or_object_elements());
4568 value = FixedArray::cast(array)->get(i);
4569 }
4570 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
4571 if (!value->IsTheHole()) {
4572 Object* result;
4573 MaybeObject* maybe_result =
4574 dictionary->AddNumberEntry(i, value, details);
4575 if (!maybe_result->ToObject(&result)) return maybe_result;
4576 dictionary = SeededNumberDictionary::cast(result);
4577 }
4578 }
4585 4579
4586 // Switch to using the dictionary as the backing storage for elements. 4580 // Switch to using the dictionary as the backing storage for elements.
4587 if (is_arguments) { 4581 if (is_arguments) {
4588 FixedArray::cast(elements())->set(1, dictionary); 4582 FixedArray::cast(elements())->set(1, dictionary);
4589 } else { 4583 } else {
4590 // Set the new map first to satify the elements type assert in 4584 // Set the new map first to satify the elements type assert in
4591 // set_elements(). 4585 // set_elements().
4592 Map* new_map; 4586 Object* new_map;
4593 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), 4587 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(),
4594 DICTIONARY_ELEMENTS); 4588 DICTIONARY_ELEMENTS);
4595 if (!maybe->To(&new_map)) return maybe; 4589 if (!maybe->ToObject(&new_map)) return maybe;
4596 set_map(new_map); 4590 set_map(Map::cast(new_map));
4597 set_elements(dictionary); 4591 set_elements(dictionary);
4598 } 4592 }
4599 4593
4600 old_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> 4594 old_map->GetHeap()->isolate()->counters()->elements_to_dictionary()->
4601 Increment(); 4595 Increment();
4602 4596
4603 #ifdef DEBUG 4597 #ifdef DEBUG
4604 if (FLAG_trace_normalization) { 4598 if (FLAG_trace_normalization) {
4605 PrintF("Object elements have been normalized:\n"); 4599 PrintF("Object elements have been normalized:\n");
4606 Print(); 4600 Print();
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
5330 SeededNumberDictionary* dictionary = NULL; 5324 SeededNumberDictionary* dictionary = NULL;
5331 { MaybeObject* maybe = NormalizeElements(); 5325 { MaybeObject* maybe = NormalizeElements();
5332 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe; 5326 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe;
5333 } 5327 }
5334 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 5328 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
5335 // Make sure that we never go back to fast case. 5329 // Make sure that we never go back to fast case.
5336 dictionary->set_requires_slow_elements(); 5330 dictionary->set_requires_slow_elements();
5337 5331
5338 // Do a map transition, other objects with this map may still 5332 // Do a map transition, other objects with this map may still
5339 // be extensible. 5333 // be extensible.
5340 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5341 Map* new_map; 5334 Map* new_map;
5342 MaybeObject* maybe = map()->Copy(); 5335 MaybeObject* maybe = map()->Copy();
5343 if (!maybe->To(&new_map)) return maybe; 5336 if (!maybe->To(&new_map)) return maybe;
5344 5337
5345 new_map->set_is_extensible(false); 5338 new_map->set_is_extensible(false);
5346 set_map(new_map); 5339 set_map(new_map);
5347 ASSERT(!map()->is_extensible()); 5340 ASSERT(!map()->is_extensible());
5348 return new_map; 5341 return new_map;
5349 } 5342 }
5350 5343
5351 5344
5352 template<typename Dictionary>
5353 static void FreezeDictionary(Dictionary* dictionary) {
5354 int capacity = dictionary->Capacity();
5355 for (int i = 0; i < capacity; i++) {
5356 Object* k = dictionary->KeyAt(i);
5357 if (dictionary->IsKey(k)) {
5358 PropertyDetails details = dictionary->DetailsAt(i);
5359 details = details.CopyAddAttributes(FROZEN);
5360 dictionary->DetailsAtPut(i, details);
5361 }
5362 }
5363 }
5364
5365
5366 MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
5367 // Freezing non-strict arguments should be handled elsewhere.
5368 ASSERT(!HasNonStrictArgumentsElements());
5369
5370 Heap* heap = isolate->heap();
5371
5372 if (map()->is_frozen()) return this;
5373
5374 if (IsAccessCheckNeeded() &&
5375 !isolate->MayNamedAccess(this,
5376 heap->undefined_value(),
5377 v8::ACCESS_KEYS)) {
5378 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS);
5379 return heap->false_value();
5380 }
5381
5382 if (IsJSGlobalProxy()) {
5383 Object* proto = GetPrototype();
5384 if (proto->IsNull()) return this;
5385 ASSERT(proto->IsJSGlobalObject());
5386 return JSObject::cast(proto)->Freeze(isolate);
5387 }
5388
5389 // It's not possible to freeze objects with external array elements
5390 if (HasExternalArrayElements()) {
5391 HandleScope scope(isolate);
5392 Handle<Object> object(this, isolate);
5393 Handle<Object> error =
5394 isolate->factory()->NewTypeError(
5395 "cant_prevent_ext_external_array_elements",
5396 HandleVector(&object, 1));
5397 return isolate->Throw(*error);
5398 }
5399
5400 SeededNumberDictionary* new_element_dictionary = NULL;
5401 if (!elements()->IsDictionary()) {
5402 int length = IsJSArray()
5403 ? Smi::cast(JSArray::cast(this)->length())->value()
5404 : elements()->length();
5405 if (length > 0) {
5406 int capacity = 0;
5407 int used = 0;
5408 GetElementsCapacityAndUsage(&capacity, &used);
5409 MaybeObject* maybe_dict = SeededNumberDictionary::Allocate(heap, used);
5410 if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
5411
5412 // Move elements to a dictionary; avoid calling NormalizeElements to avoid
5413 // unnecessary transitions.
5414 maybe_dict = CopyFastElementsToDictionary(isolate, elements(), length,
5415 new_element_dictionary);
5416 if (!maybe_dict->To(&new_element_dictionary)) return maybe_dict;
5417 } else {
5418 // No existing elements, use a pre-allocated empty backing store
5419 new_element_dictionary = heap->empty_slow_element_dictionary();
5420 }
5421 }
5422
5423 LookupResult result(isolate);
5424 map()->LookupTransition(this, heap->frozen_symbol(), &result);
5425 if (result.IsTransition()) {
5426 Map* transition_map = result.GetTransitionTarget();
5427 ASSERT(transition_map->has_dictionary_elements());
5428 ASSERT(transition_map->is_frozen());
5429 ASSERT(!transition_map->is_extensible());
5430 set_map(transition_map);
5431 } else if (HasFastProperties() && map()->CanHaveMoreTransitions()) {
5432 // Create a new descriptor array with fully-frozen properties
5433 int num_descriptors = map()->NumberOfOwnDescriptors();
5434 DescriptorArray* new_descriptors;
5435 MaybeObject* maybe_descriptors =
5436 map()->instance_descriptors()->CopyUpToAddAttributes(num_descriptors,
5437 FROZEN);
5438 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
5439
5440 Map* new_map;
5441 MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(
5442 new_descriptors, INSERT_TRANSITION, heap->frozen_symbol());
5443 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5444 new_map->freeze();
5445 new_map->set_is_extensible(false);
5446 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5447 set_map(new_map);
5448 } else {
5449 // Slow path: need to normalize properties for safety
5450 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
5451 if (maybe->IsFailure()) return maybe;
5452
5453 // Create a new map, since other objects with this map may be extensible.
5454 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5455 Map* new_map;
5456 MaybeObject* maybe_copy = map()->Copy();
5457 if (!maybe_copy->To(&new_map)) return maybe_copy;
5458 new_map->freeze();
5459 new_map->set_is_extensible(false);
5460 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
5461 set_map(new_map);
5462
5463 // Freeze dictionary-mode properties
5464 FreezeDictionary(property_dictionary());
5465 }
5466
5467 ASSERT(map()->has_dictionary_elements());
5468 if (new_element_dictionary != NULL) {
5469 set_elements(new_element_dictionary);
5470 }
5471
5472 if (elements() != heap->empty_slow_element_dictionary()) {
5473 SeededNumberDictionary* dictionary = element_dictionary();
5474 // Make sure we never go back to the fast case
5475 dictionary->set_requires_slow_elements();
5476 // Freeze all elements in the dictionary
5477 FreezeDictionary(dictionary);
5478 }
5479
5480 return this;
5481 }
5482
5483
5484 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { 5345 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
5485 StackLimitCheck check(isolate); 5346 StackLimitCheck check(isolate);
5486 if (check.HasOverflowed()) return isolate->StackOverflow(); 5347 if (check.HasOverflowed()) return isolate->StackOverflow();
5487 5348
5488 if (map()->is_deprecated()) { 5349 if (map()->is_deprecated()) {
5489 MaybeObject* maybe_failure = MigrateInstance(); 5350 MaybeObject* maybe_failure = MigrateInstance();
5490 if (maybe_failure->IsFailure()) return maybe_failure; 5351 if (maybe_failure->IsFailure()) return maybe_failure;
5491 } 5352 }
5492 5353
5493 Heap* heap = isolate->heap(); 5354 Heap* heap = isolate->heap();
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after
6498 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); 6359 ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1);
6499 6360
6500 set_transitions(transitions); 6361 set_transitions(transitions);
6501 set_owns_descriptors(false); 6362 set_owns_descriptors(false);
6502 6363
6503 return result; 6364 return result;
6504 } 6365 }
6505 6366
6506 6367
6507 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, 6368 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors,
6369 Name* name,
6508 TransitionFlag flag, 6370 TransitionFlag flag,
6509 Name* name, 6371 int descriptor_index) {
6510 SimpleTransitionFlag simple_flag) {
6511 ASSERT(descriptors->IsSortedNoDuplicates()); 6372 ASSERT(descriptors->IsSortedNoDuplicates());
6512 6373
6513 Map* result; 6374 Map* result;
6514 MaybeObject* maybe_result = CopyDropDescriptors(); 6375 MaybeObject* maybe_result = CopyDropDescriptors();
6515 if (!maybe_result->To(&result)) return maybe_result; 6376 if (!maybe_result->To(&result)) return maybe_result;
6516 6377
6517 result->InitializeDescriptors(descriptors); 6378 result->InitializeDescriptors(descriptors);
6518 6379
6519 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { 6380 if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) {
6520 TransitionArray* transitions; 6381 TransitionArray* transitions;
6382 SimpleTransitionFlag simple_flag =
6383 (descriptor_index == descriptors->number_of_descriptors() - 1)
6384 ? SIMPLE_TRANSITION
6385 : FULL_TRANSITION;
6386 ASSERT(name == descriptors->GetKey(descriptor_index));
6521 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); 6387 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag);
6522 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6388 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6389
6523 set_transitions(transitions); 6390 set_transitions(transitions);
6524 result->SetBackPointer(this); 6391 result->SetBackPointer(this);
6525 } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) { 6392 } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) {
6526 descriptors->InitializeRepresentations(Representation::Tagged()); 6393 descriptors->InitializeRepresentations(Representation::Tagged());
6527 } 6394 }
6528 6395
6529 return result; 6396 return result;
6530 } 6397 }
6531 6398
6532 6399
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
6628 JSFunction* ctor = JSFunction::cast(constructor()); 6495 JSFunction* ctor = JSFunction::cast(constructor());
6629 Map* map = ctor->initial_map(); 6496 Map* map = ctor->initial_map();
6630 DescriptorArray* descriptors = map->instance_descriptors(); 6497 DescriptorArray* descriptors = map->instance_descriptors();
6631 6498
6632 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 6499 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
6633 DescriptorArray* new_descriptors; 6500 DescriptorArray* new_descriptors;
6634 MaybeObject* maybe_descriptors = 6501 MaybeObject* maybe_descriptors =
6635 descriptors->CopyUpTo(number_of_own_descriptors); 6502 descriptors->CopyUpTo(number_of_own_descriptors);
6636 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 6503 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
6637 6504
6638 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); 6505 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
6639 } 6506 }
6640 6507
6641 6508
6642 MaybeObject* Map::Copy() { 6509 MaybeObject* Map::Copy() {
6643 DescriptorArray* descriptors = instance_descriptors(); 6510 DescriptorArray* descriptors = instance_descriptors();
6644 DescriptorArray* new_descriptors; 6511 DescriptorArray* new_descriptors;
6645 int number_of_own_descriptors = NumberOfOwnDescriptors(); 6512 int number_of_own_descriptors = NumberOfOwnDescriptors();
6646 MaybeObject* maybe_descriptors = 6513 MaybeObject* maybe_descriptors =
6647 descriptors->CopyUpTo(number_of_own_descriptors); 6514 descriptors->CopyUpTo(number_of_own_descriptors);
6648 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; 6515 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
6649 6516
6650 return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); 6517 return CopyReplaceDescriptors(new_descriptors, NULL, OMIT_TRANSITION, 0);
6651 } 6518 }
6652 6519
6653 6520
6654 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, 6521 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
6655 TransitionFlag flag) { 6522 TransitionFlag flag) {
6656 DescriptorArray* descriptors = instance_descriptors(); 6523 DescriptorArray* descriptors = instance_descriptors();
6657 6524
6658 // Ensure the key is unique. 6525 // Ensure the key is unique.
6659 MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); 6526 MaybeObject* maybe_failure = descriptor->KeyToUniqueName();
6660 if (maybe_failure->IsFailure()) return maybe_failure; 6527 if (maybe_failure->IsFailure()) return maybe_failure;
(...skipping 20 matching lines...) Expand all
6681 6548
6682 if (old_size != descriptors->number_of_descriptors()) { 6549 if (old_size != descriptors->number_of_descriptors()) {
6683 new_descriptors->SetNumberOfDescriptors(new_size); 6550 new_descriptors->SetNumberOfDescriptors(new_size);
6684 new_descriptors->Set(old_size, descriptor, witness); 6551 new_descriptors->Set(old_size, descriptor, witness);
6685 new_descriptors->Sort(); 6552 new_descriptors->Sort();
6686 } else { 6553 } else {
6687 new_descriptors->Append(descriptor, witness); 6554 new_descriptors->Append(descriptor, witness);
6688 } 6555 }
6689 6556
6690 Name* key = descriptor->GetKey(); 6557 Name* key = descriptor->GetKey();
6691 return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION); 6558 int insertion_index = new_descriptors->number_of_descriptors() - 1;
6559
6560 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
6692 } 6561 }
6693 6562
6694 6563
6695 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, 6564 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor,
6696 TransitionFlag flag) { 6565 TransitionFlag flag) {
6697 DescriptorArray* old_descriptors = instance_descriptors(); 6566 DescriptorArray* old_descriptors = instance_descriptors();
6698 6567
6699 // Ensure the key is unique. 6568 // Ensure the key is unique.
6700 MaybeObject* maybe_result = descriptor->KeyToUniqueName(); 6569 MaybeObject* maybe_result = descriptor->KeyToUniqueName();
6701 if (maybe_result->IsFailure()) return maybe_result; 6570 if (maybe_result->IsFailure()) return maybe_result;
6702 6571
6703 // We replace the key if it is already present. 6572 // We replace the key if it is already present.
6704 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); 6573 int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this);
6705 if (index != DescriptorArray::kNotFound) { 6574 if (index != DescriptorArray::kNotFound) {
6706 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); 6575 return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag);
6707 } 6576 }
6708 return CopyAddDescriptor(descriptor, flag); 6577 return CopyAddDescriptor(descriptor, flag);
6709 } 6578 }
6710 6579
6711 6580
6712 MaybeObject* DescriptorArray::CopyUpToAddAttributes( 6581 MaybeObject* DescriptorArray::CopyUpTo(int enumeration_index) {
6713 int enumeration_index, PropertyAttributes attributes) {
6714 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); 6582 if (enumeration_index == 0) return GetHeap()->empty_descriptor_array();
6715 6583
6716 int size = enumeration_index; 6584 int size = enumeration_index;
6717 6585
6718 DescriptorArray* descriptors; 6586 DescriptorArray* descriptors;
6719 MaybeObject* maybe_descriptors = Allocate(size); 6587 MaybeObject* maybe_descriptors = Allocate(size);
6720 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; 6588 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
6721 DescriptorArray::WhitenessWitness witness(descriptors); 6589 DescriptorArray::WhitenessWitness witness(descriptors);
6722 6590
6723 if (attributes != NONE) { 6591 for (int i = 0; i < size; ++i) {
6724 for (int i = 0; i < size; ++i) { 6592 descriptors->CopyFrom(i, this, i, witness);
6725 PropertyDetails details = GetDetails(i).CopyAddAttributes(attributes);
6726 Descriptor desc(GetKey(i), GetValue(i), details);
6727 descriptors->Set(i, &desc, witness);
6728 }
6729 } else {
6730 for (int i = 0; i < size; ++i) {
6731 descriptors->CopyFrom(i, this, i, witness);
6732 }
6733 } 6593 }
6734 6594
6735 if (number_of_descriptors() != enumeration_index) descriptors->Sort(); 6595 if (number_of_descriptors() != enumeration_index) descriptors->Sort();
6736 6596
6737 return descriptors; 6597 return descriptors;
6738 } 6598 }
6739 6599
6740 6600
6741 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, 6601 MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors,
6742 Descriptor* descriptor, 6602 Descriptor* descriptor,
(...skipping 20 matching lines...) Expand all
6763 if (i == insertion_index) { 6623 if (i == insertion_index) {
6764 new_descriptors->Set(i, descriptor, witness); 6624 new_descriptors->Set(i, descriptor, witness);
6765 } else { 6625 } else {
6766 new_descriptors->CopyFrom(i, descriptors, i, witness); 6626 new_descriptors->CopyFrom(i, descriptors, i, witness);
6767 } 6627 }
6768 } 6628 }
6769 6629
6770 // Re-sort if descriptors were removed. 6630 // Re-sort if descriptors were removed.
6771 if (new_size != descriptors->length()) new_descriptors->Sort(); 6631 if (new_size != descriptors->length()) new_descriptors->Sort();
6772 6632
6773 SimpleTransitionFlag simple_flag = 6633 return CopyReplaceDescriptors(new_descriptors, key, flag, insertion_index);
6774 (insertion_index == descriptors->number_of_descriptors() - 1)
6775 ? SIMPLE_TRANSITION
6776 : FULL_TRANSITION;
6777 return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag);
6778 } 6634 }
6779 6635
6780 6636
6781 void Map::UpdateCodeCache(Handle<Map> map, 6637 void Map::UpdateCodeCache(Handle<Map> map,
6782 Handle<Name> name, 6638 Handle<Name> name,
6783 Handle<Code> code) { 6639 Handle<Code> code) {
6784 Isolate* isolate = map->GetIsolate(); 6640 Isolate* isolate = map->GetIsolate();
6785 CALL_HEAP_FUNCTION_VOID(isolate, 6641 CALL_HEAP_FUNCTION_VOID(isolate,
6786 map->UpdateCodeCache(*name, *code)); 6642 map->UpdateCodeCache(*name, *code));
6787 } 6643 }
(...skipping 6732 matching lines...) Expand 10 before | Expand all | Expand 10 after
13520 13376
13521 template class HashTable<ObjectHashTableShape<2>, Object*>; 13377 template class HashTable<ObjectHashTableShape<2>, Object*>;
13522 13378
13523 template class Dictionary<NameDictionaryShape, Name*>; 13379 template class Dictionary<NameDictionaryShape, Name*>;
13524 13380
13525 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; 13381 template class Dictionary<SeededNumberDictionaryShape, uint32_t>;
13526 13382
13527 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; 13383 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>;
13528 13384
13529 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: 13385 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::
13530 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); 13386 Allocate(Heap* heap, int at_least_space_for);
13531 13387
13532 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: 13388 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
13533 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); 13389 Allocate(Heap* heap, int at_least_space_for);
13534 13390
13535 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: 13391 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::
13536 Allocate(Heap* heap, int n, PretenureFlag pretenure); 13392 Allocate(Heap* heap, int n);
13537 13393
13538 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( 13394 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut(
13539 uint32_t, Object*); 13395 uint32_t, Object*);
13540 13396
13541 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: 13397 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::
13542 AtPut(uint32_t, Object*); 13398 AtPut(uint32_t, Object*);
13543 13399
13544 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: 13400 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>::
13545 SlowReverseLookup(Object* value); 13401 SlowReverseLookup(Object* value);
13546 13402
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after
14470 int entry = cache->FindInsertionEntry(key.Hash()); 14326 int entry = cache->FindInsertionEntry(key.Hash());
14471 cache->set(EntryToIndex(entry), array); 14327 cache->set(EntryToIndex(entry), array);
14472 cache->set(EntryToIndex(entry) + 1, value); 14328 cache->set(EntryToIndex(entry) + 1, value);
14473 cache->ElementAdded(); 14329 cache->ElementAdded();
14474 return cache; 14330 return cache;
14475 } 14331 }
14476 14332
14477 14333
14478 template<typename Shape, typename Key> 14334 template<typename Shape, typename Key>
14479 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, 14335 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap,
14480 int at_least_space_for, 14336 int at_least_space_for) {
14481 PretenureFlag pretenure) {
14482 Object* obj; 14337 Object* obj;
14483 { MaybeObject* maybe_obj = 14338 { MaybeObject* maybe_obj =
14484 HashTable<Shape, Key>::Allocate( 14339 HashTable<Shape, Key>::Allocate(heap, at_least_space_for);
14485 heap,
14486 at_least_space_for,
14487 HashTable<Shape, Key>::USE_DEFAULT_MINIMUM_CAPACITY,
14488 pretenure);
14489 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 14340 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14490 } 14341 }
14491 // Initialize the next enumeration index. 14342 // Initialize the next enumeration index.
14492 Dictionary<Shape, Key>::cast(obj)-> 14343 Dictionary<Shape, Key>::cast(obj)->
14493 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 14344 SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
14494 return obj; 14345 return obj;
14495 } 14346 }
14496 14347
14497 14348
14498 void NameDictionary::DoGenerateNewEnumerationIndices( 14349 void NameDictionary::DoGenerateNewEnumerationIndices(
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
15603 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 15454 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
15604 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 15455 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
15605 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 15456 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
15606 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 15457 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
15607 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 15458 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
15608 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 15459 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
15609 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 15460 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
15610 } 15461 }
15611 15462
15612 } } // namespace v8::internal 15463 } } // 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