| 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 |