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

Side by Side Diff: src/objects.cc

Issue 8820014: Support Smi->Double->HeapObject transitions in constructed Arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 9 years 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 8115 matching lines...) Expand 10 before | Expand all | Expand 10 after
8126 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); 8126 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out);
8127 PrintF(out, "\n"); 8127 PrintF(out, "\n");
8128 } 8128 }
8129 #endif // ENABLE_DISASSEMBLER 8129 #endif // ENABLE_DISASSEMBLER
8130 8130
8131 8131
8132 static void CopyFastElementsToFast(FixedArray* source, 8132 static void CopyFastElementsToFast(FixedArray* source,
8133 FixedArray* destination, 8133 FixedArray* destination,
8134 WriteBarrierMode mode) { 8134 WriteBarrierMode mode) {
8135 int count = source->length(); 8135 int count = source->length();
8136 int copy_size = Min(count, destination->length());
8136 if (mode == SKIP_WRITE_BARRIER || 8137 if (mode == SKIP_WRITE_BARRIER ||
8137 !Page::FromAddress(destination->address())->IsFlagSet( 8138 !Page::FromAddress(destination->address())->IsFlagSet(
8138 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) { 8139 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) {
8139 ASSERT(count <= destination->length());
8140 Address to = destination->address() + FixedArray::kHeaderSize; 8140 Address to = destination->address() + FixedArray::kHeaderSize;
8141 Address from = source->address() + FixedArray::kHeaderSize; 8141 Address from = source->address() + FixedArray::kHeaderSize;
8142 memcpy(reinterpret_cast<void*>(to), 8142 memcpy(reinterpret_cast<void*>(to),
8143 reinterpret_cast<void*>(from), 8143 reinterpret_cast<void*>(from),
8144 kPointerSize * count); 8144 kPointerSize * copy_size);
8145 } else { 8145 } else {
8146 for (int i = 0; i < count; ++i) { 8146 for (int i = 0; i < copy_size; ++i) {
8147 destination->set(i, source->get(i), mode); 8147 destination->set(i, source->get(i), mode);
8148 } 8148 }
8149 } 8149 }
8150 } 8150 }
8151 8151
8152 8152
8153 static void CopySlowElementsToFast(NumberDictionary* source, 8153 static void CopySlowElementsToFast(NumberDictionary* source,
8154 FixedArray* destination, 8154 FixedArray* destination,
8155 WriteBarrierMode mode) { 8155 WriteBarrierMode mode) {
8156 int destination_length = destination->length();
8156 for (int i = 0; i < source->Capacity(); ++i) { 8157 for (int i = 0; i < source->Capacity(); ++i) {
8157 Object* key = source->KeyAt(i); 8158 Object* key = source->KeyAt(i);
8158 if (key->IsNumber()) { 8159 if (key->IsNumber()) {
8159 uint32_t entry = static_cast<uint32_t>(key->Number()); 8160 uint32_t entry = static_cast<uint32_t>(key->Number());
8160 destination->set(entry, source->ValueAt(i), mode); 8161 if (entry < static_cast<uint32_t>(destination_length)) {
8162 destination->set(entry, source->ValueAt(i), mode);
8163 }
8161 } 8164 }
8162 } 8165 }
8163 } 8166 }
8164 8167
8165 8168
8166 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 8169 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
8167 int capacity, 8170 int capacity,
8168 int length, 8171 int length,
8169 SetFastElementsCapacityMode set_capacity_mode) { 8172 SetFastElementsCapacityMode set_capacity_mode) {
8170 Heap* heap = GetHeap(); 8173 Heap* heap = GetHeap();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
8361 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8364 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8362 } 8365 }
8363 new_elements = FixedArray::cast(obj); 8366 new_elements = FixedArray::cast(obj);
8364 } 8367 }
8365 set_elements(new_elements); 8368 set_elements(new_elements);
8366 return this; 8369 return this;
8367 } 8370 }
8368 8371
8369 8372
8370 void JSArray::Expand(int required_size) { 8373 void JSArray::Expand(int required_size) {
8371 Handle<JSArray> self(this); 8374 GetIsolate()->factory()->SetElementsCapacityAndLength(
8372 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 8375 Handle<JSArray>(this), required_size, Smi::cast(length())->value());
8373 int old_size = old_backing->length();
8374 int new_size = required_size > old_size ? required_size : old_size;
8375 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size);
8376 // Can't use this any more now because we may have had a GC!
8377 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
8378 GetIsolate()->factory()->SetContent(self, new_backing);
8379 } 8376 }
8380 8377
8381 8378
8382 MaybeObject* JSObject::SetElementsLength(Object* len) { 8379 MaybeObject* JSObject::SetElementsLength(Object* len) {
8383 // We should never end in here with a pixel or external array. 8380 // We should never end in here with a pixel or external array.
8384 ASSERT(AllowsSetElementsLength()); 8381 ASSERT(AllowsSetElementsLength());
8385 return GetElementsAccessor()->SetLength(this, len); 8382 return GetElementsAccessor()->SetLength(this, len);
8386 } 8383 }
8387 8384
8388 8385
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
8522 real_receiver->set_map(Map::cast(new_map)); 8519 real_receiver->set_map(Map::cast(new_map));
8523 8520
8524 heap->ClearInstanceofCache(); 8521 heap->ClearInstanceofCache();
8525 ASSERT(size == Size()); 8522 ASSERT(size == Size());
8526 return value; 8523 return value;
8527 } 8524 }
8528 8525
8529 8526
8530 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, 8527 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args,
8531 uint32_t first_arg, 8528 uint32_t first_arg,
8532 uint32_t arg_count) { 8529 uint32_t arg_count,
8530 EnsureElementsMode mode) {
8533 // Elements in |Arguments| are ordered backwards (because they're on the 8531 // Elements in |Arguments| are ordered backwards (because they're on the
8534 // stack), but the method that's called here iterates over them in forward 8532 // stack), but the method that's called here iterates over them in forward
8535 // direction. 8533 // direction.
8536 return EnsureCanContainElements( 8534 return EnsureCanContainElements(
8537 args->arguments() - first_arg - (arg_count - 1), 8535 args->arguments() - first_arg - (arg_count - 1),
8538 arg_count); 8536 arg_count, mode);
8539 } 8537 }
8540 8538
8541 8539
8542 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { 8540 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
8543 switch (GetElementsKind()) { 8541 switch (GetElementsKind()) {
8544 case FAST_SMI_ONLY_ELEMENTS: 8542 case FAST_SMI_ONLY_ELEMENTS:
8545 case FAST_ELEMENTS: { 8543 case FAST_ELEMENTS: {
8546 uint32_t length = IsJSArray() ? 8544 uint32_t length = IsJSArray() ?
8547 static_cast<uint32_t> 8545 static_cast<uint32_t>
8548 (Smi::cast(JSArray::cast(this)->length())->value()) : 8546 (Smi::cast(JSArray::cast(this)->length())->value()) :
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
9480 return isolate->heap()->null_value(); 9478 return isolate->heap()->null_value();
9481 } 9479 }
9482 9480
9483 9481
9484 MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind( 9482 MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind(
9485 ElementsKind to_kind) { 9483 ElementsKind to_kind) {
9486 ElementsKind from_kind = map()->elements_kind(); 9484 ElementsKind from_kind = map()->elements_kind();
9487 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 9485 FixedArrayBase* elms = FixedArrayBase::cast(elements());
9488 uint32_t capacity = static_cast<uint32_t>(elms->length()); 9486 uint32_t capacity = static_cast<uint32_t>(elms->length());
9489 uint32_t length = capacity; 9487 uint32_t length = capacity;
9488
9490 if (IsJSArray()) { 9489 if (IsJSArray()) {
9491 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 9490 Object* raw_length = JSArray::cast(this)->length();
9491 if (raw_length->IsUndefined()) {
9492 // If length is undefined, then JSArray is being initialized and has no
9493 // elements, assume a length of zero.
9494 length = 0;
9495 } else {
9496 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
9497 }
9492 } 9498 }
9493 if (from_kind == FAST_SMI_ONLY_ELEMENTS) { 9499
9494 if (to_kind == FAST_DOUBLE_ELEMENTS) { 9500 if ((from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) ||
9495 MaybeObject* maybe_result = 9501 (length == 0)) {
9496 SetFastDoubleElementsCapacityAndLength(capacity, length); 9502 MaybeObject* maybe_new_map = GetElementsTransitionMap(to_kind);
9497 if (maybe_result->IsFailure()) return maybe_result; 9503 Map* new_map;
9498 return this; 9504 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9499 } else if (to_kind == FAST_ELEMENTS) { 9505 if (FLAG_trace_elements_transitions) {
9500 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); 9506 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms);
9501 Map* new_map;
9502 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9503 if (FLAG_trace_elements_transitions) {
9504 PrintElementsTransition(stdout, from_kind, elms, FAST_ELEMENTS, elms);
9505 }
9506 set_map(new_map);
9507 return this;
9508 } 9507 }
9509 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 9508 set_map(new_map);
9509 return this;
9510 }
9511
9512 if (from_kind == FAST_SMI_ONLY_ELEMENTS &&
9513 to_kind == FAST_DOUBLE_ELEMENTS) {
9514 MaybeObject* maybe_result =
9515 SetFastDoubleElementsCapacityAndLength(capacity, length);
9516 if (maybe_result->IsFailure()) return maybe_result;
9517 return this;
9518 }
9519
9520 if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) {
9510 MaybeObject* maybe_result = SetFastElementsCapacityAndLength( 9521 MaybeObject* maybe_result = SetFastElementsCapacityAndLength(
9511 capacity, length, kDontAllowSmiOnlyElements); 9522 capacity, length, kDontAllowSmiOnlyElements);
9512 if (maybe_result->IsFailure()) return maybe_result; 9523 if (maybe_result->IsFailure()) return maybe_result;
9513 return this; 9524 return this;
9514 } 9525 }
9526
9515 // This method should never be called for any other case than the ones 9527 // This method should never be called for any other case than the ones
9516 // handled above. 9528 // handled above.
9517 UNREACHABLE(); 9529 UNREACHABLE();
9518 return GetIsolate()->heap()->null_value(); 9530 return GetIsolate()->heap()->null_value();
9519 } 9531 }
9520 9532
9521 9533
9522 // static 9534 // static
9523 bool Map::IsValidElementsTransition(ElementsKind from_kind, 9535 bool Map::IsValidElementsTransition(ElementsKind from_kind,
9524 ElementsKind to_kind) { 9536 ElementsKind to_kind) {
(...skipping 3015 matching lines...) Expand 10 before | Expand all | Expand 10 after
12540 if (break_point_objects()->IsUndefined()) return 0; 12552 if (break_point_objects()->IsUndefined()) return 0;
12541 // Single break point. 12553 // Single break point.
12542 if (!break_point_objects()->IsFixedArray()) return 1; 12554 if (!break_point_objects()->IsFixedArray()) return 1;
12543 // Multiple break points. 12555 // Multiple break points.
12544 return FixedArray::cast(break_point_objects())->length(); 12556 return FixedArray::cast(break_point_objects())->length();
12545 } 12557 }
12546 #endif // ENABLE_DEBUGGER_SUPPORT 12558 #endif // ENABLE_DEBUGGER_SUPPORT
12547 12559
12548 12560
12549 } } // namespace v8::internal 12561 } } // 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