| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 2293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2304 } | 2304 } |
| 2305 | 2305 |
| 2306 // We are storing the new map using release store after creating a filler for | 2306 // We are storing the new map using release store after creating a filler for |
| 2307 // the left-over space to avoid races with the sweeper thread. | 2307 // the left-over space to avoid races with the sweeper thread. |
| 2308 this->synchronized_set_map(new_map); | 2308 this->synchronized_set_map(new_map); |
| 2309 | 2309 |
| 2310 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 2310 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
| 2311 self->set_resource(resource); | 2311 self->set_resource(resource); |
| 2312 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 2312 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
| 2313 | 2313 |
| 2314 heap->AdjustLiveBytes(this, new_size - size, Heap::CONCURRENT_TO_SWEEPER); | 2314 heap->AdjustLiveBytes(this, new_size - size); |
| 2315 return true; | 2315 return true; |
| 2316 } | 2316 } |
| 2317 | 2317 |
| 2318 | 2318 |
| 2319 bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { | 2319 bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { |
| 2320 // Externalizing twice leaks the external resource, so it's | 2320 // Externalizing twice leaks the external resource, so it's |
| 2321 // prohibited by the API. | 2321 // prohibited by the API. |
| 2322 DCHECK(!this->IsExternalString()); | 2322 DCHECK(!this->IsExternalString()); |
| 2323 DCHECK(!resource->IsCompressible()); | 2323 DCHECK(!resource->IsCompressible()); |
| 2324 #ifdef ENABLE_SLOW_DCHECKS | 2324 #ifdef ENABLE_SLOW_DCHECKS |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 } | 2370 } |
| 2371 | 2371 |
| 2372 // We are storing the new map using release store after creating a filler for | 2372 // We are storing the new map using release store after creating a filler for |
| 2373 // the left-over space to avoid races with the sweeper thread. | 2373 // the left-over space to avoid races with the sweeper thread. |
| 2374 this->synchronized_set_map(new_map); | 2374 this->synchronized_set_map(new_map); |
| 2375 | 2375 |
| 2376 ExternalOneByteString* self = ExternalOneByteString::cast(this); | 2376 ExternalOneByteString* self = ExternalOneByteString::cast(this); |
| 2377 self->set_resource(resource); | 2377 self->set_resource(resource); |
| 2378 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 2378 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
| 2379 | 2379 |
| 2380 heap->AdjustLiveBytes(this, new_size - size, Heap::CONCURRENT_TO_SWEEPER); | 2380 heap->AdjustLiveBytes(this, new_size - size); |
| 2381 return true; | 2381 return true; |
| 2382 } | 2382 } |
| 2383 | 2383 |
| 2384 void String::StringShortPrint(StringStream* accumulator, bool show_details) { | 2384 void String::StringShortPrint(StringStream* accumulator, bool show_details) { |
| 2385 int len = length(); | 2385 int len = length(); |
| 2386 if (len > kMaxShortPrintLength) { | 2386 if (len > kMaxShortPrintLength) { |
| 2387 accumulator->Add("<Very long string[%u]>", len); | 2387 accumulator->Add("<Very long string[%u]>", len); |
| 2388 return; | 2388 return; |
| 2389 } | 2389 } |
| 2390 | 2390 |
| (...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3420 } | 3420 } |
| 3421 } else { | 3421 } else { |
| 3422 object->RawFastPropertyAtPut(index, value); | 3422 object->RawFastPropertyAtPut(index, value); |
| 3423 } | 3423 } |
| 3424 } | 3424 } |
| 3425 | 3425 |
| 3426 | 3426 |
| 3427 // If there are properties in the new backing store, trim it to the correct | 3427 // If there are properties in the new backing store, trim it to the correct |
| 3428 // size and install the backing store into the object. | 3428 // size and install the backing store into the object. |
| 3429 if (external > 0) { | 3429 if (external > 0) { |
| 3430 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array, inobject); | 3430 heap->RightTrimFixedArray(*array, inobject); |
| 3431 object->set_properties(*array); | 3431 object->set_properties(*array); |
| 3432 } | 3432 } |
| 3433 | 3433 |
| 3434 // Create filler object past the new instance size. | 3434 // Create filler object past the new instance size. |
| 3435 int new_instance_size = new_map->instance_size(); | 3435 int new_instance_size = new_map->instance_size(); |
| 3436 int instance_size_delta = old_map->instance_size() - new_instance_size; | 3436 int instance_size_delta = old_map->instance_size() - new_instance_size; |
| 3437 DCHECK(instance_size_delta >= 0); | 3437 DCHECK(instance_size_delta >= 0); |
| 3438 | 3438 |
| 3439 if (instance_size_delta > 0) { | 3439 if (instance_size_delta > 0) { |
| 3440 Address address = object->address(); | 3440 Address address = object->address(); |
| 3441 heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta, | 3441 heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta, |
| 3442 ClearRecordedSlots::kYes); | 3442 ClearRecordedSlots::kYes); |
| 3443 heap->AdjustLiveBytes(*object, -instance_size_delta, | 3443 heap->AdjustLiveBytes(*object, -instance_size_delta); |
| 3444 Heap::CONCURRENT_TO_SWEEPER); | |
| 3445 } | 3444 } |
| 3446 | 3445 |
| 3447 // We are storing the new map using release store after creating a filler for | 3446 // We are storing the new map using release store after creating a filler for |
| 3448 // the left-over space to avoid races with the sweeper thread. | 3447 // the left-over space to avoid races with the sweeper thread. |
| 3449 object->synchronized_set_map(*new_map); | 3448 object->synchronized_set_map(*new_map); |
| 3450 } | 3449 } |
| 3451 | 3450 |
| 3452 void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map, | 3451 void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map, |
| 3453 int expected_additional_properties) { | 3452 int expected_additional_properties) { |
| 3454 // The global object is always normalized. | 3453 // The global object is always normalized. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3529 | 3528 |
| 3530 // Resize the object in the heap if necessary. | 3529 // Resize the object in the heap if necessary. |
| 3531 int new_instance_size = new_map->instance_size(); | 3530 int new_instance_size = new_map->instance_size(); |
| 3532 int instance_size_delta = map->instance_size() - new_instance_size; | 3531 int instance_size_delta = map->instance_size() - new_instance_size; |
| 3533 DCHECK(instance_size_delta >= 0); | 3532 DCHECK(instance_size_delta >= 0); |
| 3534 | 3533 |
| 3535 if (instance_size_delta > 0) { | 3534 if (instance_size_delta > 0) { |
| 3536 Heap* heap = isolate->heap(); | 3535 Heap* heap = isolate->heap(); |
| 3537 heap->CreateFillerObjectAt(object->address() + new_instance_size, | 3536 heap->CreateFillerObjectAt(object->address() + new_instance_size, |
| 3538 instance_size_delta, ClearRecordedSlots::kYes); | 3537 instance_size_delta, ClearRecordedSlots::kYes); |
| 3539 heap->AdjustLiveBytes(*object, -instance_size_delta, | 3538 heap->AdjustLiveBytes(*object, -instance_size_delta); |
| 3540 Heap::CONCURRENT_TO_SWEEPER); | |
| 3541 } | 3539 } |
| 3542 | 3540 |
| 3543 // We are storing the new map using release store after creating a filler for | 3541 // We are storing the new map using release store after creating a filler for |
| 3544 // the left-over space to avoid races with the sweeper thread. | 3542 // the left-over space to avoid races with the sweeper thread. |
| 3545 object->synchronized_set_map(*new_map); | 3543 object->synchronized_set_map(*new_map); |
| 3546 | 3544 |
| 3547 object->set_properties(*dictionary); | 3545 object->set_properties(*dictionary); |
| 3548 | 3546 |
| 3549 // Ensure that in-object space of slow-mode object does not contain random | 3547 // Ensure that in-object space of slow-mode object does not contain random |
| 3550 // garbage. | 3548 // garbage. |
| (...skipping 6583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10134 array->GetIsolate()->factory()->NewUninitializedFixedArray(capacity); | 10132 array->GetIsolate()->factory()->NewUninitializedFixedArray(capacity); |
| 10135 array->CopyTo(0, *new_array, 0, array->length()); | 10133 array->CopyTo(0, *new_array, 0, array->length()); |
| 10136 new_array->FillWithHoles(array->length(), new_array->length()); | 10134 new_array->FillWithHoles(array->length(), new_array->length()); |
| 10137 new_array->set(index, *value); | 10135 new_array->set(index, *value); |
| 10138 return new_array; | 10136 return new_array; |
| 10139 } | 10137 } |
| 10140 | 10138 |
| 10141 void FixedArray::Shrink(int new_length) { | 10139 void FixedArray::Shrink(int new_length) { |
| 10142 DCHECK(0 <= new_length && new_length <= length()); | 10140 DCHECK(0 <= new_length && new_length <= length()); |
| 10143 if (new_length < length()) { | 10141 if (new_length < length()) { |
| 10144 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | 10142 GetHeap()->RightTrimFixedArray(this, length() - new_length); |
| 10145 this, length() - new_length); | |
| 10146 } | 10143 } |
| 10147 } | 10144 } |
| 10148 | 10145 |
| 10149 | 10146 |
| 10150 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { | 10147 void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) { |
| 10151 DisallowHeapAllocation no_gc; | 10148 DisallowHeapAllocation no_gc; |
| 10152 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); | 10149 WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc); |
| 10153 for (int index = 0; index < len; index++) { | 10150 for (int index = 0; index < len; index++) { |
| 10154 dest->set(dest_pos+index, get(pos+index), mode); | 10151 dest->set(dest_pos+index, get(pos+index), mode); |
| 10155 } | 10152 } |
| (...skipping 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12043 | 12040 |
| 12044 Address start_of_string = string->address(); | 12041 Address start_of_string = string->address(); |
| 12045 DCHECK_OBJECT_ALIGNED(start_of_string); | 12042 DCHECK_OBJECT_ALIGNED(start_of_string); |
| 12046 DCHECK_OBJECT_ALIGNED(start_of_string + new_size); | 12043 DCHECK_OBJECT_ALIGNED(start_of_string + new_size); |
| 12047 | 12044 |
| 12048 Heap* heap = string->GetHeap(); | 12045 Heap* heap = string->GetHeap(); |
| 12049 // Sizes are pointer size aligned, so that we can use filler objects | 12046 // Sizes are pointer size aligned, so that we can use filler objects |
| 12050 // that are a multiple of pointer size. | 12047 // that are a multiple of pointer size. |
| 12051 heap->CreateFillerObjectAt(start_of_string + new_size, delta, | 12048 heap->CreateFillerObjectAt(start_of_string + new_size, delta, |
| 12052 ClearRecordedSlots::kNo); | 12049 ClearRecordedSlots::kNo); |
| 12053 heap->AdjustLiveBytes(*string, -delta, Heap::CONCURRENT_TO_SWEEPER); | 12050 heap->AdjustLiveBytes(*string, -delta); |
| 12054 | 12051 |
| 12055 // We are storing the new length using release store after creating a filler | 12052 // We are storing the new length using release store after creating a filler |
| 12056 // for the left-over space to avoid races with the sweeper thread. | 12053 // for the left-over space to avoid races with the sweeper thread. |
| 12057 string->synchronized_set_length(new_length); | 12054 string->synchronized_set_length(new_length); |
| 12058 | 12055 |
| 12059 if (new_length == 0) return heap->isolate()->factory()->empty_string(); | 12056 if (new_length == 0) return heap->isolate()->factory()->empty_string(); |
| 12060 return string; | 12057 return string; |
| 12061 } | 12058 } |
| 12062 | 12059 |
| 12063 | 12060 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12463 code_map->get(src + kCachedCodeOffset)); | 12460 code_map->get(src + kCachedCodeOffset)); |
| 12464 code_map->set(dst + kLiteralsOffset, | 12461 code_map->set(dst + kLiteralsOffset, |
| 12465 code_map->get(src + kLiteralsOffset)); | 12462 code_map->get(src + kLiteralsOffset)); |
| 12466 code_map->set(dst + kOsrAstIdOffset, | 12463 code_map->set(dst + kOsrAstIdOffset, |
| 12467 code_map->get(src + kOsrAstIdOffset)); | 12464 code_map->get(src + kOsrAstIdOffset)); |
| 12468 } | 12465 } |
| 12469 dst += kEntryLength; | 12466 dst += kEntryLength; |
| 12470 } | 12467 } |
| 12471 if (dst != length) { | 12468 if (dst != length) { |
| 12472 // Always trim even when array is cleared because of heap verifier. | 12469 // Always trim even when array is cleared because of heap verifier. |
| 12473 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map, | 12470 heap->RightTrimFixedArray(code_map, length - dst); |
| 12474 length - dst); | |
| 12475 if (code_map->length() == kEntriesStart) { | 12471 if (code_map->length() == kEntriesStart) { |
| 12476 ClearOptimizedCodeMap(); | 12472 ClearOptimizedCodeMap(); |
| 12477 } | 12473 } |
| 12478 } | 12474 } |
| 12479 } | 12475 } |
| 12480 | 12476 |
| 12481 | 12477 |
| 12482 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { | 12478 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { |
| 12483 FixedArray* code_map = optimized_code_map(); | 12479 FixedArray* code_map = optimized_code_map(); |
| 12484 DCHECK(shrink_by % kEntryLength == 0); | 12480 DCHECK(shrink_by % kEntryLength == 0); |
| 12485 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 12481 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
| 12486 // Always trim even when array is cleared because of heap verifier. | 12482 // Always trim even when array is cleared because of heap verifier. |
| 12487 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, | 12483 GetHeap()->RightTrimFixedArray(code_map, shrink_by); |
| 12488 shrink_by); | |
| 12489 if (code_map->length() == kEntriesStart) { | 12484 if (code_map->length() == kEntriesStart) { |
| 12490 ClearOptimizedCodeMap(); | 12485 ClearOptimizedCodeMap(); |
| 12491 } | 12486 } |
| 12492 } | 12487 } |
| 12493 | 12488 |
| 12494 // static | 12489 // static |
| 12495 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { | 12490 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { |
| 12496 Handle<SharedFunctionInfo> shared(function->shared()); | 12491 Handle<SharedFunctionInfo> shared(function->shared()); |
| 12497 Handle<Context> native_context(function->context()->native_context()); | 12492 Handle<Context> native_context(function->context()->native_context()); |
| 12498 if (function->literals() == | 12493 if (function->literals() == |
| (...skipping 7923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20422 // depend on this. | 20417 // depend on this. |
| 20423 return DICTIONARY_ELEMENTS; | 20418 return DICTIONARY_ELEMENTS; |
| 20424 } | 20419 } |
| 20425 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20420 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20426 return kind; | 20421 return kind; |
| 20427 } | 20422 } |
| 20428 } | 20423 } |
| 20429 | 20424 |
| 20430 } // namespace internal | 20425 } // namespace internal |
| 20431 } // namespace v8 | 20426 } // namespace v8 |
| OLD | NEW |