OLD | NEW |
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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 isolate); | 364 isolate); |
365 } | 365 } |
366 } | 366 } |
367 UNREACHABLE(); | 367 UNREACHABLE(); |
368 return isolate->factory()->undefined_value(); | 368 return isolate->factory()->undefined_value(); |
369 } | 369 } |
370 | 370 |
371 | 371 |
372 Handle<FixedArray> JSObject::EnsureWritableFastElements( | 372 Handle<FixedArray> JSObject::EnsureWritableFastElements( |
373 Handle<JSObject> object) { | 373 Handle<JSObject> object) { |
374 CALL_HEAP_FUNCTION(object->GetIsolate(), | 374 ASSERT(object->HasFastSmiOrObjectElements()); |
375 object->EnsureWritableFastElements(), | 375 Isolate* isolate = object->GetIsolate(); |
376 FixedArray); | 376 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
| 377 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
| 378 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
| 379 elems, isolate->factory()->fixed_array_map()); |
| 380 object->set_elements(*writable_elems); |
| 381 isolate->counters()->cow_arrays_converted()->Increment(); |
| 382 return writable_elems; |
377 } | 383 } |
378 | 384 |
379 | 385 |
380 MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object, | 386 MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object, |
381 Handle<Object> receiver, | 387 Handle<Object> receiver, |
382 Handle<Object> structure, | 388 Handle<Object> structure, |
383 Handle<Name> name) { | 389 Handle<Name> name) { |
384 Isolate* isolate = name->GetIsolate(); | 390 Isolate* isolate = name->GetIsolate(); |
385 // To accommodate both the old and the new api we switch on the | 391 // To accommodate both the old and the new api we switch on the |
386 // data structure used to store the callbacks. Eventually foreign | 392 // data structure used to store the callbacks. Eventually foreign |
(...skipping 8022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8409 for (int i = 0; i < result->length(); i++) { | 8415 for (int i = 0; i < result->length(); i++) { |
8410 Object* current = result->get(i); | 8416 Object* current = result->get(i); |
8411 ASSERT(current->IsNumber() || current->IsName()); | 8417 ASSERT(current->IsNumber() || current->IsName()); |
8412 } | 8418 } |
8413 } | 8419 } |
8414 #endif | 8420 #endif |
8415 return result; | 8421 return result; |
8416 } | 8422 } |
8417 | 8423 |
8418 | 8424 |
8419 MaybeObject* FixedArray::CopySize(int new_length, PretenureFlag pretenure) { | |
8420 Heap* heap = GetHeap(); | |
8421 if (new_length == 0) return heap->empty_fixed_array(); | |
8422 Object* obj; | |
8423 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length, pretenure); | |
8424 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
8425 } | |
8426 FixedArray* result = FixedArray::cast(obj); | |
8427 // Copy the content | |
8428 DisallowHeapAllocation no_gc; | |
8429 int len = length(); | |
8430 if (new_length < len) len = new_length; | |
8431 // We are taking the map from the old fixed array so the map is sure to | |
8432 // be an immortal immutable object. | |
8433 result->set_map_no_write_barrier(map()); | |
8434 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | |
8435 for (int i = 0; i < len; i++) { | |
8436 result->set(i, get(i), mode); | |
8437 } | |
8438 return result; | |
8439 } | |
8440 | |
8441 | |
8442 Handle<FixedArray> FixedArray::CopySize( | 8425 Handle<FixedArray> FixedArray::CopySize( |
8443 Handle<FixedArray> array, int new_length, PretenureFlag pretenure) { | 8426 Handle<FixedArray> array, int new_length, PretenureFlag pretenure) { |
8444 Isolate* isolate = array->GetIsolate(); | 8427 Isolate* isolate = array->GetIsolate(); |
8445 CALL_HEAP_FUNCTION(isolate, | 8428 if (new_length == 0) return isolate->factory()->empty_fixed_array(); |
8446 array->CopySize(new_length, pretenure), | 8429 Handle<FixedArray> result = |
8447 FixedArray); | 8430 isolate->factory()->NewFixedArray(new_length, pretenure); |
| 8431 // Copy the content |
| 8432 DisallowHeapAllocation no_gc; |
| 8433 int len = array->length(); |
| 8434 if (new_length < len) len = new_length; |
| 8435 // We are taking the map from the old fixed array so the map is sure to |
| 8436 // be an immortal immutable object. |
| 8437 result->set_map_no_write_barrier(array->map()); |
| 8438 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 8439 for (int i = 0; i < len; i++) { |
| 8440 result->set(i, array->get(i), mode); |
| 8441 } |
| 8442 return result; |
8448 } | 8443 } |
8449 | 8444 |
8450 | 8445 |
8451 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { | 8446 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { |
8452 DisallowHeapAllocation no_gc; | 8447 DisallowHeapAllocation no_gc; |
8453 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); | 8448 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); |
8454 for (int index = 0; index < len; index++) { | 8449 for (int index = 0; index < len; index++) { |
8455 dest->set(dest_pos+index, get(pos+index), mode); | 8450 dest->set(dest_pos+index, get(pos+index), mode); |
8456 } | 8451 } |
8457 } | 8452 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8589 return copy; | 8584 return copy; |
8590 } | 8585 } |
8591 | 8586 |
8592 | 8587 |
8593 Object* AccessorPair::GetComponent(AccessorComponent component) { | 8588 Object* AccessorPair::GetComponent(AccessorComponent component) { |
8594 Object* accessor = get(component); | 8589 Object* accessor = get(component); |
8595 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; | 8590 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; |
8596 } | 8591 } |
8597 | 8592 |
8598 | 8593 |
8599 MaybeObject* DeoptimizationInputData::Allocate(Isolate* isolate, | 8594 Handle<DeoptimizationInputData> DeoptimizationInputData::New( |
8600 int deopt_entry_count, | 8595 Isolate* isolate, |
8601 PretenureFlag pretenure) { | 8596 int deopt_entry_count, |
| 8597 PretenureFlag pretenure) { |
8602 ASSERT(deopt_entry_count > 0); | 8598 ASSERT(deopt_entry_count > 0); |
8603 return isolate->heap()->AllocateFixedArray(LengthFor(deopt_entry_count), | 8599 return Handle<DeoptimizationInputData>::cast( |
8604 pretenure); | 8600 isolate->factory()->NewFixedArray( |
| 8601 LengthFor(deopt_entry_count), pretenure)); |
8605 } | 8602 } |
8606 | 8603 |
8607 | 8604 |
8608 MaybeObject* DeoptimizationOutputData::Allocate(Isolate* isolate, | 8605 Handle<DeoptimizationOutputData> DeoptimizationOutputData::New( |
8609 int number_of_deopt_points, | 8606 Isolate* isolate, |
8610 PretenureFlag pretenure) { | 8607 int number_of_deopt_points, |
8611 if (number_of_deopt_points == 0) return isolate->heap()->empty_fixed_array(); | 8608 PretenureFlag pretenure) { |
8612 return isolate->heap()->AllocateFixedArray( | 8609 Handle<FixedArray> result; |
8613 LengthOfFixedArray(number_of_deopt_points), pretenure); | 8610 if (number_of_deopt_points == 0) { |
| 8611 result = isolate->factory()->empty_fixed_array(); |
| 8612 } else { |
| 8613 result = isolate->factory()->NewFixedArray( |
| 8614 LengthOfFixedArray(number_of_deopt_points), pretenure); |
| 8615 } |
| 8616 return Handle<DeoptimizationOutputData>::cast(result); |
8614 } | 8617 } |
8615 | 8618 |
8616 | 8619 |
8617 #ifdef DEBUG | 8620 #ifdef DEBUG |
8618 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { | 8621 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { |
8619 if (IsEmpty()) return other->IsEmpty(); | 8622 if (IsEmpty()) return other->IsEmpty(); |
8620 if (other->IsEmpty()) return false; | 8623 if (other->IsEmpty()) return false; |
8621 if (length() != other->length()) return false; | 8624 if (length() != other->length()) return false; |
8622 for (int i = 0; i < length(); ++i) { | 8625 for (int i = 0; i < length(); ++i) { |
8623 if (get(i) != other->get(i)) return false; | 8626 if (get(i) != other->get(i)) return false; |
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10048 // No optimized code map. | 10051 // No optimized code map. |
10049 ASSERT_EQ(0, Smi::cast(*value)->value()); | 10052 ASSERT_EQ(0, Smi::cast(*value)->value()); |
10050 // Create 3 entries per context {context, code, literals}. | 10053 // Create 3 entries per context {context, code, literals}. |
10051 new_code_map = isolate->factory()->NewFixedArray(kInitialLength); | 10054 new_code_map = isolate->factory()->NewFixedArray(kInitialLength); |
10052 old_length = kEntriesStart; | 10055 old_length = kEntriesStart; |
10053 } else { | 10056 } else { |
10054 // Copy old map and append one new entry. | 10057 // Copy old map and append one new entry. |
10055 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); | 10058 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); |
10056 ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id)); | 10059 ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id)); |
10057 old_length = old_code_map->length(); | 10060 old_length = old_code_map->length(); |
10058 new_code_map = isolate->factory()->CopySizeFixedArray( | 10061 new_code_map = FixedArray::CopySize( |
10059 old_code_map, old_length + kEntryLength); | 10062 old_code_map, old_length + kEntryLength); |
10060 // Zap the old map for the sake of the heap verifier. | 10063 // Zap the old map for the sake of the heap verifier. |
10061 if (Heap::ShouldZapGarbage()) { | 10064 if (Heap::ShouldZapGarbage()) { |
10062 Object** data = old_code_map->data_start(); | 10065 Object** data = old_code_map->data_start(); |
10063 MemsetPointer(data, isolate->heap()->the_hole_value(), old_length); | 10066 MemsetPointer(data, isolate->heap()->the_hole_value(), old_length); |
10064 } | 10067 } |
10065 } | 10068 } |
10066 new_code_map->set(old_length + kContextOffset, *native_context); | 10069 new_code_map->set(old_length + kContextOffset, *native_context); |
10067 new_code_map->set(old_length + kCachedCodeOffset, *code); | 10070 new_code_map->set(old_length + kCachedCodeOffset, *code); |
10068 new_code_map->set(old_length + kLiteralsOffset, *literals); | 10071 new_code_map->set(old_length + kLiteralsOffset, *literals); |
(...skipping 2030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12099 const int header = kProtoTransitionHeaderSize; | 12102 const int header = kProtoTransitionHeaderSize; |
12100 | 12103 |
12101 Handle<FixedArray> cache(map->GetPrototypeTransitions()); | 12104 Handle<FixedArray> cache(map->GetPrototypeTransitions()); |
12102 int capacity = (cache->length() - header) / step; | 12105 int capacity = (cache->length() - header) / step; |
12103 int transitions = map->NumberOfProtoTransitions() + 1; | 12106 int transitions = map->NumberOfProtoTransitions() + 1; |
12104 | 12107 |
12105 if (transitions > capacity) { | 12108 if (transitions > capacity) { |
12106 if (capacity > kMaxCachedPrototypeTransitions) return map; | 12109 if (capacity > kMaxCachedPrototypeTransitions) return map; |
12107 | 12110 |
12108 // Grow array by factor 2 over and above what we need. | 12111 // Grow array by factor 2 over and above what we need. |
12109 Factory* factory = map->GetIsolate()->factory(); | 12112 cache = FixedArray::CopySize(cache, transitions * 2 * step + header); |
12110 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header); | |
12111 | 12113 |
12112 SetPrototypeTransitions(map, cache); | 12114 SetPrototypeTransitions(map, cache); |
12113 } | 12115 } |
12114 | 12116 |
12115 // Reload number of transitions as GC might shrink them. | 12117 // Reload number of transitions as GC might shrink them. |
12116 int last = map->NumberOfProtoTransitions(); | 12118 int last = map->NumberOfProtoTransitions(); |
12117 int entry = header + last * step; | 12119 int entry = header + last * step; |
12118 | 12120 |
12119 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); | 12121 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); |
12120 cache->set(entry + kProtoTransitionMapOffset, *target_map); | 12122 cache->set(entry + kProtoTransitionMapOffset, *target_map); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12216 Handle<Object> object) { | 12218 Handle<Object> object) { |
12217 GroupStartIndexes starts(*entries); | 12219 GroupStartIndexes starts(*entries); |
12218 int start = starts.at(group); | 12220 int start = starts.at(group); |
12219 int end = starts.at(group + 1); | 12221 int end = starts.at(group + 1); |
12220 int number_of_entries = starts.number_of_entries(); | 12222 int number_of_entries = starts.number_of_entries(); |
12221 // Check for existing entry to avoid duplicates. | 12223 // Check for existing entry to avoid duplicates. |
12222 for (int i = start; i < end; i++) { | 12224 for (int i = start; i < end; i++) { |
12223 if (entries->object_at(i) == *object) return entries; | 12225 if (entries->object_at(i) == *object) return entries; |
12224 } | 12226 } |
12225 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { | 12227 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
12226 Factory* factory = entries->GetIsolate()->factory(); | |
12227 int capacity = kCodesStartIndex + number_of_entries + 1; | 12228 int capacity = kCodesStartIndex + number_of_entries + 1; |
12228 if (capacity > 5) capacity = capacity * 5 / 4; | 12229 if (capacity > 5) capacity = capacity * 5 / 4; |
12229 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( | 12230 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( |
12230 factory->CopySizeFixedArray(entries, capacity, TENURED)); | 12231 FixedArray::CopySize(entries, capacity, TENURED)); |
12231 // The number of codes can change after GC. | 12232 // The number of codes can change after GC. |
12232 starts.Recompute(*entries); | 12233 starts.Recompute(*entries); |
12233 start = starts.at(group); | 12234 start = starts.at(group); |
12234 end = starts.at(group + 1); | 12235 end = starts.at(group + 1); |
12235 number_of_entries = starts.number_of_entries(); | 12236 number_of_entries = starts.number_of_entries(); |
12236 for (int i = 0; i < number_of_entries; i++) { | 12237 for (int i = 0; i < number_of_entries; i++) { |
12237 entries->clear_at(i); | 12238 entries->clear_at(i); |
12238 } | 12239 } |
12239 // If the old fixed array was empty, we need to reset counters of the | 12240 // If the old fixed array was empty, we need to reset counters of the |
12240 // new array. | 12241 // new array. |
(...skipping 5085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17326 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17327 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17327 static const char* error_messages_[] = { | 17328 static const char* error_messages_[] = { |
17328 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17329 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17329 }; | 17330 }; |
17330 #undef ERROR_MESSAGES_TEXTS | 17331 #undef ERROR_MESSAGES_TEXTS |
17331 return error_messages_[reason]; | 17332 return error_messages_[reason]; |
17332 } | 17333 } |
17333 | 17334 |
17334 | 17335 |
17335 } } // namespace v8::internal | 17336 } } // namespace v8::internal |
OLD | NEW |