| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 124 |
| 125 | 125 |
| 126 static Failure* ThrowArrayLengthRangeError(Heap* heap) { | 126 static Failure* ThrowArrayLengthRangeError(Heap* heap) { |
| 127 HandleScope scope(heap->isolate()); | 127 HandleScope scope(heap->isolate()); |
| 128 return heap->isolate()->Throw( | 128 return heap->isolate()->Throw( |
| 129 *heap->isolate()->factory()->NewRangeError("invalid_array_length", | 129 *heap->isolate()->factory()->NewRangeError("invalid_array_length", |
| 130 HandleVector<Object>(NULL, 0))); | 130 HandleVector<Object>(NULL, 0))); |
| 131 } | 131 } |
| 132 | 132 |
| 133 | 133 |
| 134 void CopyObjectToObjectElements(AssertNoAllocation* no_gc, | 134 void CopyObjectToObjectElements(FixedArray* from, |
| 135 FixedArray* from_obj, | |
| 136 ElementsKind from_kind, | 135 ElementsKind from_kind, |
| 137 uint32_t from_start, | 136 uint32_t from_start, |
| 138 FixedArray* to_obj, | 137 FixedArray* to, |
| 139 ElementsKind to_kind, | 138 ElementsKind to_kind, |
| 140 uint32_t to_start, | 139 uint32_t to_start, |
| 141 int copy_size) { | 140 int raw_copy_size, |
| 142 ASSERT(to_obj->map() != HEAP->fixed_cow_array_map()); | 141 WriteBarrierMode mode) { |
| 142 ASSERT(to->map() != HEAP->fixed_cow_array_map()); |
| 143 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); | 143 ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); |
| 144 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 144 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
| 145 if (copy_size == -1) { | 145 int copy_size = raw_copy_size; |
| 146 copy_size = Min(from_obj->length() - from_start, | 146 if (raw_copy_size < 0) { |
| 147 to_obj->length() - to_start); | 147 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 148 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 149 copy_size = Min(from->length() - from_start, |
| 150 to->length() - to_start); |
| 151 #ifdef DEBUG |
| 152 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 153 // marked with the hole. |
| 154 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 155 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 156 ASSERT(to->get(i)->IsTheHole()); |
| 157 } |
| 158 } |
| 159 #endif |
| 148 } | 160 } |
| 149 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 161 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
| 150 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 162 (copy_size + static_cast<int>(from_start)) <= from->length()); |
| 151 if (copy_size == 0) return; | 163 if (copy_size == 0) return; |
| 152 Address to = to_obj->address() + FixedArray::kHeaderSize; | 164 Address to_address = to->address() + FixedArray::kHeaderSize; |
| 153 Address from = from_obj->address() + FixedArray::kHeaderSize; | 165 Address from_address = from->address() + FixedArray::kHeaderSize; |
| 154 CopyWords(reinterpret_cast<Object**>(to) + to_start, | 166 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, |
| 155 reinterpret_cast<Object**>(from) + from_start, | 167 reinterpret_cast<Object**>(from_address) + from_start, |
| 156 copy_size); | 168 copy_size); |
| 157 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) { | 169 if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS && |
| 158 Heap* heap = from_obj->GetHeap(); | 170 mode == UPDATE_WRITE_BARRIER) { |
| 159 WriteBarrierMode mode = to_obj->GetWriteBarrierMode(*no_gc); | 171 Heap* heap = from->GetHeap(); |
| 160 if (mode == UPDATE_WRITE_BARRIER) { | 172 if (!heap->InNewSpace(to)) { |
| 161 heap->RecordWrites(to_obj->address(), | 173 heap->RecordWrites(to->address(), |
| 162 to_obj->OffsetOfElementAt(to_start), | 174 to->OffsetOfElementAt(to_start), |
| 163 copy_size); | 175 copy_size); |
| 164 } | 176 } |
| 165 heap->incremental_marking()->RecordWrites(to_obj); | 177 heap->incremental_marking()->RecordWrites(to); |
| 166 } | 178 } |
| 167 } | 179 } |
| 168 | 180 |
| 169 | 181 |
| 170 | |
| 171 | |
| 172 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, | 182 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
| 173 uint32_t from_start, | 183 uint32_t from_start, |
| 174 FixedArray* to, | 184 FixedArray* to, |
| 175 ElementsKind to_kind, | 185 ElementsKind to_kind, |
| 176 uint32_t to_start, | 186 uint32_t to_start, |
| 177 int copy_size) { | 187 int raw_copy_size, |
| 188 WriteBarrierMode mode) { |
| 189 int copy_size = raw_copy_size; |
| 190 Heap* heap = from->GetHeap(); |
| 191 if (raw_copy_size < 0) { |
| 192 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 193 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 194 copy_size = from->max_number_key() + 1 - from_start; |
| 195 #ifdef DEBUG |
| 196 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 197 // marked with the hole. |
| 198 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 199 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 200 ASSERT(to->get(i)->IsTheHole()); |
| 201 } |
| 202 } |
| 203 #endif |
| 204 } |
| 205 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length()); |
| 178 ASSERT(to != from); | 206 ASSERT(to != from); |
| 179 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 207 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
| 180 ASSERT(copy_size == -1 || | 208 if (copy_size == 0) return; |
| 181 (copy_size + static_cast<int>(to_start)) <= to->length()); | 209 for (int i = 0; i < copy_size; i++) { |
| 182 WriteBarrierMode mode = to_kind == FAST_ELEMENTS | 210 int entry = from->FindEntry(i + from_start); |
| 183 ? UPDATE_WRITE_BARRIER | 211 if (entry != SeededNumberDictionary::kNotFound) { |
| 184 : SKIP_WRITE_BARRIER; | 212 Object* value = from->ValueAt(entry); |
| 185 uint32_t copy_limit = (copy_size == -1) | 213 ASSERT(!value->IsTheHole()); |
| 186 ? to->length() | 214 to->set(i + to_start, value, SKIP_WRITE_BARRIER); |
| 187 : Min(to_start + copy_size, static_cast<uint32_t>(to->length())); | 215 } else { |
| 188 for (int i = 0; i < from->Capacity(); ++i) { | 216 to->set_the_hole(i + to_start); |
| 189 Object* key = from->KeyAt(i); | |
| 190 if (key->IsNumber()) { | |
| 191 uint32_t entry = static_cast<uint32_t>(key->Number()); | |
| 192 if (entry >= to_start && entry < copy_limit) { | |
| 193 Object* value = from->ValueAt(i); | |
| 194 ASSERT(to_kind == FAST_ELEMENTS || value->IsSmi()); | |
| 195 to->set(entry, value, mode); | |
| 196 } | |
| 197 } | 217 } |
| 198 } | 218 } |
| 219 if (to_kind == FAST_ELEMENTS) { |
| 220 if (!heap->InNewSpace(to)) { |
| 221 heap->RecordWrites(to->address(), |
| 222 to->OffsetOfElementAt(to_start), |
| 223 copy_size); |
| 224 } |
| 225 heap->incremental_marking()->RecordWrites(to); |
| 226 } |
| 199 } | 227 } |
| 200 | 228 |
| 201 | 229 |
| 202 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( | 230 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
| 203 FixedDoubleArray* from_obj, | 231 FixedDoubleArray* from, |
| 204 uint32_t from_start, | 232 uint32_t from_start, |
| 205 FixedArray* to_obj, | 233 FixedArray* to, |
| 206 ElementsKind to_kind, | 234 ElementsKind to_kind, |
| 207 uint32_t to_start, | 235 uint32_t to_start, |
| 208 int copy_size) { | 236 int raw_copy_size) { |
| 209 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); | 237 ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); |
| 210 if (copy_size == -1) { | 238 int copy_size = raw_copy_size; |
| 211 copy_size = Min(from_obj->length() - from_start, | 239 if (raw_copy_size < 0) { |
| 212 to_obj->length() - to_start); | 240 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 241 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 242 copy_size = Min(from->length() - from_start, |
| 243 to->length() - to_start); |
| 244 #ifdef DEBUG |
| 245 // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already |
| 246 // marked with the hole. |
| 247 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 248 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 249 ASSERT(to->get(i)->IsTheHole()); |
| 250 } |
| 251 } |
| 252 #endif |
| 213 } | 253 } |
| 214 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 254 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
| 215 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 255 (copy_size + static_cast<int>(from_start)) <= from->length()); |
| 216 if (copy_size == 0) return from_obj; | 256 if (copy_size == 0) return from; |
| 217 for (int i = 0; i < copy_size; ++i) { | 257 for (int i = 0; i < copy_size; ++i) { |
| 218 if (to_kind == FAST_SMI_ONLY_ELEMENTS) { | 258 if (to_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 219 UNIMPLEMENTED(); | 259 UNIMPLEMENTED(); |
| 220 return Failure::Exception(); | 260 return Failure::Exception(); |
| 221 } else { | 261 } else { |
| 222 MaybeObject* maybe_value = from_obj->get(i + from_start); | 262 MaybeObject* maybe_value = from->get(i + from_start); |
| 223 Object* value; | 263 Object* value; |
| 224 ASSERT(to_kind == FAST_ELEMENTS); | 264 ASSERT(to_kind == FAST_ELEMENTS); |
| 225 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects | 265 // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects |
| 226 // iteratively, the allocate must succeed within a single GC cycle, | 266 // iteratively, the allocate must succeed within a single GC cycle, |
| 227 // otherwise the retry after the GC will also fail. In order to ensure | 267 // otherwise the retry after the GC will also fail. In order to ensure |
| 228 // that no GC is triggered, allocate HeapNumbers from old space if they | 268 // that no GC is triggered, allocate HeapNumbers from old space if they |
| 229 // can't be taken from new space. | 269 // can't be taken from new space. |
| 230 if (!maybe_value->ToObject(&value)) { | 270 if (!maybe_value->ToObject(&value)) { |
| 231 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); | 271 ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); |
| 232 Heap* heap = from_obj->GetHeap(); | 272 Heap* heap = from->GetHeap(); |
| 233 MaybeObject* maybe_value_object = | 273 MaybeObject* maybe_value_object = |
| 234 heap->AllocateHeapNumber(from_obj->get_scalar(i + from_start), | 274 heap->AllocateHeapNumber(from->get_scalar(i + from_start), |
| 235 TENURED); | 275 TENURED); |
| 236 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; | 276 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; |
| 237 } | 277 } |
| 238 to_obj->set(i + to_start, value, UPDATE_WRITE_BARRIER); | 278 to->set(i + to_start, value, UPDATE_WRITE_BARRIER); |
| 239 } | 279 } |
| 240 } | 280 } |
| 241 return to_obj; | 281 return to; |
| 242 } | 282 } |
| 243 | 283 |
| 244 | 284 |
| 245 static void CopyDoubleToDoubleElements(FixedDoubleArray* from_obj, | 285 static void CopyDoubleToDoubleElements(FixedDoubleArray* from, |
| 246 uint32_t from_start, | 286 uint32_t from_start, |
| 247 FixedDoubleArray* to_obj, | 287 FixedDoubleArray* to, |
| 248 uint32_t to_start, | 288 uint32_t to_start, |
| 249 int copy_size) { | 289 int raw_copy_size) { |
| 250 if (copy_size == -1) { | 290 int copy_size = raw_copy_size; |
| 251 copy_size = Min(from_obj->length() - from_start, | 291 if (raw_copy_size < 0) { |
| 252 to_obj->length() - to_start); | 292 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 293 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 294 copy_size = Min(from->length() - from_start, |
| 295 to->length() - to_start); |
| 296 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 297 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 298 to->set_the_hole(i); |
| 299 } |
| 300 } |
| 253 } | 301 } |
| 254 ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() && | 302 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
| 255 (copy_size + static_cast<int>(from_start)) <= from_obj->length())); | 303 (copy_size + static_cast<int>(from_start)) <= from->length()); |
| 256 if (copy_size == 0) return; | 304 if (copy_size == 0) return; |
| 257 Address to = to_obj->address() + FixedDoubleArray::kHeaderSize; | 305 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
| 258 Address from = from_obj->address() + FixedDoubleArray::kHeaderSize; | 306 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
| 259 to += kDoubleSize * to_start; | 307 to_address += kDoubleSize * to_start; |
| 260 from += kDoubleSize * from_start; | 308 from_address += kDoubleSize * from_start; |
| 261 int words_per_double = (kDoubleSize / kPointerSize); | 309 int words_per_double = (kDoubleSize / kPointerSize); |
| 262 CopyWords(reinterpret_cast<Object**>(to), | 310 CopyWords(reinterpret_cast<Object**>(to_address), |
| 263 reinterpret_cast<Object**>(from), | 311 reinterpret_cast<Object**>(from_address), |
| 264 words_per_double * copy_size); | 312 words_per_double * copy_size); |
| 265 } | 313 } |
| 266 | 314 |
| 267 | 315 |
| 316 static void CopyObjectToDoubleElements(FixedArray* from, |
| 317 uint32_t from_start, |
| 318 FixedDoubleArray* to, |
| 319 uint32_t to_start, |
| 320 int raw_copy_size) { |
| 321 int copy_size = raw_copy_size; |
| 322 if (raw_copy_size < 0) { |
| 323 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 324 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 325 copy_size = from->length() - from_start; |
| 326 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 327 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 328 to->set_the_hole(i); |
| 329 } |
| 330 } |
| 331 } |
| 332 ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
| 333 (copy_size + static_cast<int>(from_start)) <= from->length()); |
| 334 if (copy_size == 0) return; |
| 335 for (int i = 0; i < copy_size; i++) { |
| 336 Object* hole_or_object = from->get(i + from_start); |
| 337 if (hole_or_object->IsTheHole()) { |
| 338 to->set_the_hole(i + to_start); |
| 339 } else { |
| 340 to->set(i + to_start, hole_or_object->Number()); |
| 341 } |
| 342 } |
| 343 } |
| 344 |
| 345 |
| 346 static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, |
| 347 uint32_t from_start, |
| 348 FixedDoubleArray* to, |
| 349 uint32_t to_start, |
| 350 int raw_copy_size) { |
| 351 int copy_size = raw_copy_size; |
| 352 if (copy_size < 0) { |
| 353 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
| 354 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 355 copy_size = from->max_number_key() + 1 - from_start; |
| 356 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 357 for (int i = to_start + copy_size; i < to->length(); ++i) { |
| 358 to->set_the_hole(i); |
| 359 } |
| 360 } |
| 361 } |
| 362 ASSERT(copy_size + static_cast<int>(to_start) <= to->length()); |
| 363 if (copy_size == 0) return; |
| 364 for (int i = 0; i < copy_size; i++) { |
| 365 int entry = from->FindEntry(i + from_start); |
| 366 if (entry != SeededNumberDictionary::kNotFound) { |
| 367 to->set(i + to_start, from->ValueAt(entry)->Number()); |
| 368 } else { |
| 369 to->set_the_hole(i + to_start); |
| 370 } |
| 371 } |
| 372 } |
| 373 |
| 374 |
| 268 // Base class for element handler implementations. Contains the | 375 // Base class for element handler implementations. Contains the |
| 269 // the common logic for objects with different ElementsKinds. | 376 // the common logic for objects with different ElementsKinds. |
| 270 // Subclasses must specialize method for which the element | 377 // Subclasses must specialize method for which the element |
| 271 // implementation differs from the base class implementation. | 378 // implementation differs from the base class implementation. |
| 272 // | 379 // |
| 273 // This class is intended to be used in the following way: | 380 // This class is intended to be used in the following way: |
| 274 // | 381 // |
| 275 // class SomeElementsAccessor : | 382 // class SomeElementsAccessor : |
| 276 // public ElementsAccessorBase<SomeElementsAccessor, | 383 // public ElementsAccessorBase<SomeElementsAccessor, |
| 277 // BackingStoreClass> { | 384 // BackingStoreClass> { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 469 |
| 363 virtual MaybeObject* Delete(JSObject* obj, | 470 virtual MaybeObject* Delete(JSObject* obj, |
| 364 uint32_t key, | 471 uint32_t key, |
| 365 JSReceiver::DeleteMode mode) = 0; | 472 JSReceiver::DeleteMode mode) = 0; |
| 366 | 473 |
| 367 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 474 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
| 368 uint32_t from_start, | 475 uint32_t from_start, |
| 369 FixedArrayBase* to, | 476 FixedArrayBase* to, |
| 370 ElementsKind to_kind, | 477 ElementsKind to_kind, |
| 371 uint32_t to_start, | 478 uint32_t to_start, |
| 372 int copy_size) { | 479 int copy_size, |
| 480 WriteBarrierMode mode) { |
| 373 UNREACHABLE(); | 481 UNREACHABLE(); |
| 374 return NULL; | 482 return NULL; |
| 375 } | 483 } |
| 376 | 484 |
| 377 virtual MaybeObject* CopyElements(JSObject* from_holder, | 485 virtual MaybeObject* CopyElements(JSObject* from_holder, |
| 378 uint32_t from_start, | 486 uint32_t from_start, |
| 379 FixedArrayBase* to, | 487 FixedArrayBase* to, |
| 380 ElementsKind to_kind, | 488 ElementsKind to_kind, |
| 381 uint32_t to_start, | 489 uint32_t to_start, |
| 382 int copy_size, | 490 int copy_size, |
| 491 WriteBarrierMode mode, |
| 383 FixedArrayBase* from) { | 492 FixedArrayBase* from) { |
| 384 if (from == NULL) { | 493 if (from == NULL) { |
| 385 from = from_holder->elements(); | 494 from = from_holder->elements(); |
| 386 } | 495 } |
| 496 if (from->length() == 0) { |
| 497 return from; |
| 498 } |
| 387 return ElementsAccessorSubclass::CopyElementsImpl( | 499 return ElementsAccessorSubclass::CopyElementsImpl( |
| 388 from, from_start, to, to_kind, to_start, copy_size); | 500 from, from_start, to, to_kind, to_start, copy_size, mode); |
| 389 } | 501 } |
| 390 | 502 |
| 391 virtual MaybeObject* AddElementsToFixedArray(Object* receiver, | 503 virtual MaybeObject* AddElementsToFixedArray(Object* receiver, |
| 392 JSObject* holder, | 504 JSObject* holder, |
| 393 FixedArray* to, | 505 FixedArray* to, |
| 394 FixedArrayBase* from) { | 506 FixedArrayBase* from) { |
| 395 int len0 = to->length(); | 507 int len0 = to->length(); |
| 396 #ifdef DEBUG | 508 #ifdef DEBUG |
| 397 if (FLAG_enable_slow_asserts) { | 509 if (FLAG_enable_slow_asserts) { |
| 398 for (int i = 0; i < len0; i++) { | 510 for (int i = 0; i < len0; i++) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 } | 727 } |
| 616 } | 728 } |
| 617 return heap->true_value(); | 729 return heap->true_value(); |
| 618 } | 730 } |
| 619 | 731 |
| 620 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 732 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
| 621 uint32_t from_start, | 733 uint32_t from_start, |
| 622 FixedArrayBase* to, | 734 FixedArrayBase* to, |
| 623 ElementsKind to_kind, | 735 ElementsKind to_kind, |
| 624 uint32_t to_start, | 736 uint32_t to_start, |
| 625 int copy_size) { | 737 int copy_size, |
| 738 WriteBarrierMode mode) { |
| 626 switch (to_kind) { | 739 switch (to_kind) { |
| 627 case FAST_SMI_ONLY_ELEMENTS: | 740 case FAST_SMI_ONLY_ELEMENTS: |
| 628 case FAST_ELEMENTS: { | 741 case FAST_ELEMENTS: { |
| 629 AssertNoAllocation no_gc; | |
| 630 CopyObjectToObjectElements( | 742 CopyObjectToObjectElements( |
| 631 &no_gc, FixedArray::cast(from), ElementsTraits::Kind, from_start, | 743 FixedArray::cast(from), ElementsTraits::Kind, from_start, |
| 632 FixedArray::cast(to), to_kind, to_start, copy_size); | 744 FixedArray::cast(to), to_kind, to_start, copy_size, mode); |
| 633 return from; | 745 return from; |
| 634 } | 746 } |
| 747 case FAST_DOUBLE_ELEMENTS: |
| 748 CopyObjectToDoubleElements( |
| 749 FixedArray::cast(from), from_start, |
| 750 FixedDoubleArray::cast(to), to_start, copy_size); |
| 751 return from; |
| 635 default: | 752 default: |
| 636 UNREACHABLE(); | 753 UNREACHABLE(); |
| 637 } | 754 } |
| 638 return to->GetHeap()->undefined_value(); | 755 return to->GetHeap()->undefined_value(); |
| 639 } | 756 } |
| 640 | 757 |
| 641 | 758 |
| 642 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, | 759 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, |
| 643 uint32_t capacity, | 760 uint32_t capacity, |
| 644 uint32_t length) { | 761 uint32_t length) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; | 802 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; |
| 686 friend class FastElementsAccessor<FastDoubleElementsAccessor, | 803 friend class FastElementsAccessor<FastDoubleElementsAccessor, |
| 687 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, | 804 ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, |
| 688 kDoubleSize>; | 805 kDoubleSize>; |
| 689 | 806 |
| 690 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 807 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
| 691 uint32_t from_start, | 808 uint32_t from_start, |
| 692 FixedArrayBase* to, | 809 FixedArrayBase* to, |
| 693 ElementsKind to_kind, | 810 ElementsKind to_kind, |
| 694 uint32_t to_start, | 811 uint32_t to_start, |
| 695 int copy_size) { | 812 int copy_size, |
| 813 WriteBarrierMode mode) { |
| 696 switch (to_kind) { | 814 switch (to_kind) { |
| 697 case FAST_SMI_ONLY_ELEMENTS: | 815 case FAST_SMI_ONLY_ELEMENTS: |
| 698 case FAST_ELEMENTS: | 816 case FAST_ELEMENTS: |
| 699 return CopyDoubleToObjectElements( | 817 return CopyDoubleToObjectElements( |
| 700 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), | 818 FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), |
| 701 to_kind, to_start, copy_size); | 819 to_kind, to_start, copy_size); |
| 702 case FAST_DOUBLE_ELEMENTS: | 820 case FAST_DOUBLE_ELEMENTS: |
| 703 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, | 821 CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, |
| 704 FixedDoubleArray::cast(to), | 822 FixedDoubleArray::cast(to), |
| 705 to_start, copy_size); | 823 to_start, copy_size); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 1100 } |
| 983 } | 1101 } |
| 984 return heap->true_value(); | 1102 return heap->true_value(); |
| 985 } | 1103 } |
| 986 | 1104 |
| 987 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1105 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
| 988 uint32_t from_start, | 1106 uint32_t from_start, |
| 989 FixedArrayBase* to, | 1107 FixedArrayBase* to, |
| 990 ElementsKind to_kind, | 1108 ElementsKind to_kind, |
| 991 uint32_t to_start, | 1109 uint32_t to_start, |
| 992 int copy_size) { | 1110 int copy_size, |
| 1111 WriteBarrierMode mode) { |
| 993 switch (to_kind) { | 1112 switch (to_kind) { |
| 994 case FAST_SMI_ONLY_ELEMENTS: | 1113 case FAST_SMI_ONLY_ELEMENTS: |
| 995 case FAST_ELEMENTS: | 1114 case FAST_ELEMENTS: |
| 996 CopyDictionaryToObjectElements( | 1115 CopyDictionaryToObjectElements( |
| 997 SeededNumberDictionary::cast(from), from_start, | 1116 SeededNumberDictionary::cast(from), from_start, |
| 998 FixedArray::cast(to), to_kind, to_start, copy_size); | 1117 FixedArray::cast(to), to_kind, to_start, copy_size, mode); |
| 1118 return from; |
| 1119 case FAST_DOUBLE_ELEMENTS: |
| 1120 CopyDictionaryToDoubleElements( |
| 1121 SeededNumberDictionary::cast(from), from_start, |
| 1122 FixedDoubleArray::cast(to), to_start, copy_size); |
| 999 return from; | 1123 return from; |
| 1000 default: | 1124 default: |
| 1001 UNREACHABLE(); | 1125 UNREACHABLE(); |
| 1002 } | 1126 } |
| 1003 return to->GetHeap()->undefined_value(); | 1127 return to->GetHeap()->undefined_value(); |
| 1004 } | 1128 } |
| 1005 | 1129 |
| 1006 | 1130 |
| 1007 protected: | 1131 protected: |
| 1008 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1132 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 } | 1245 } |
| 1122 } | 1246 } |
| 1123 return obj->GetHeap()->true_value(); | 1247 return obj->GetHeap()->true_value(); |
| 1124 } | 1248 } |
| 1125 | 1249 |
| 1126 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1250 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
| 1127 uint32_t from_start, | 1251 uint32_t from_start, |
| 1128 FixedArrayBase* to, | 1252 FixedArrayBase* to, |
| 1129 ElementsKind to_kind, | 1253 ElementsKind to_kind, |
| 1130 uint32_t to_start, | 1254 uint32_t to_start, |
| 1131 int copy_size) { | 1255 int copy_size, |
| 1256 WriteBarrierMode mode) { |
| 1132 FixedArray* parameter_map = FixedArray::cast(from); | 1257 FixedArray* parameter_map = FixedArray::cast(from); |
| 1133 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1258 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1134 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1259 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
| 1135 return accessor->CopyElements(NULL, from_start, to, to_kind, | 1260 return accessor->CopyElements(NULL, from_start, to, to_kind, |
| 1136 to_start, copy_size, arguments); | 1261 to_start, copy_size, mode, arguments); |
| 1137 } | 1262 } |
| 1138 | 1263 |
| 1139 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { | 1264 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { |
| 1140 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1265 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 1141 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1266 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
| 1142 ForArray(arguments)->GetCapacity(arguments)); | 1267 ForArray(arguments)->GetCapacity(arguments)); |
| 1143 } | 1268 } |
| 1144 | 1269 |
| 1145 static uint32_t GetKeyForIndexImpl(FixedArray* dict, | 1270 static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
| 1146 uint32_t index) { | 1271 uint32_t index) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1287 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 1412 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
| 1288 new_backing_store->set(0, length); | 1413 new_backing_store->set(0, length); |
| 1289 { MaybeObject* result = array->SetContent(new_backing_store); | 1414 { MaybeObject* result = array->SetContent(new_backing_store); |
| 1290 if (result->IsFailure()) return result; | 1415 if (result->IsFailure()) return result; |
| 1291 } | 1416 } |
| 1292 return array; | 1417 return array; |
| 1293 } | 1418 } |
| 1294 | 1419 |
| 1295 | 1420 |
| 1296 } } // namespace v8::internal | 1421 } } // namespace v8::internal |
| OLD | NEW |