| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 161 |
| 162 | 162 |
| 163 static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { | 163 static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { |
| 164 isolate->Throw( | 164 isolate->Throw( |
| 165 *isolate->factory()->NewRangeError("invalid_array_length", | 165 *isolate->factory()->NewRangeError("invalid_array_length", |
| 166 HandleVector<Object>(NULL, 0))); | 166 HandleVector<Object>(NULL, 0))); |
| 167 return Handle<Object>(); | 167 return Handle<Object>(); |
| 168 } | 168 } |
| 169 | 169 |
| 170 | 170 |
| 171 static void CopyObjectToObjectElements(FixedArrayBase* from_base, | 171 static void CopyObjectToObjectElements(Handle<FixedArrayBase> from_base, |
| 172 ElementsKind from_kind, | 172 ElementsKind from_kind, |
| 173 uint32_t from_start, | 173 uint32_t from_start, |
| 174 FixedArrayBase* to_base, | 174 Handle<FixedArrayBase> to_base, |
| 175 ElementsKind to_kind, | 175 ElementsKind to_kind, |
| 176 uint32_t to_start, | 176 uint32_t to_start, |
| 177 int raw_copy_size) { | 177 int raw_copy_size) { |
| 178 ASSERT(to_base->map() != | 178 ASSERT(to_base->map() != |
| 179 from_base->GetIsolate()->heap()->fixed_cow_array_map()); | 179 from_base->GetIsolate()->heap()->fixed_cow_array_map()); |
| 180 DisallowHeapAllocation no_allocation; | 180 DisallowHeapAllocation no_allocation; |
| 181 int copy_size = raw_copy_size; | 181 int copy_size = raw_copy_size; |
| 182 if (raw_copy_size < 0) { | 182 if (raw_copy_size < 0) { |
| 183 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 183 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 184 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 184 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 185 copy_size = Min(from_base->length() - from_start, | 185 copy_size = Min(from_base->length() - from_start, |
| 186 to_base->length() - to_start); | 186 to_base->length() - to_start); |
| 187 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 187 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 188 int start = to_start + copy_size; | 188 int start = to_start + copy_size; |
| 189 int length = to_base->length() - start; | 189 int length = to_base->length() - start; |
| 190 if (length > 0) { | 190 if (length > 0) { |
| 191 Heap* heap = from_base->GetHeap(); | 191 Heap* heap = from_base->GetHeap(); |
| 192 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 192 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
| 193 heap->the_hole_value(), length); | 193 heap->the_hole_value(), length); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 197 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 198 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 198 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 199 if (copy_size == 0) return; | 199 if (copy_size == 0) return; |
| 200 FixedArray* from = FixedArray::cast(from_base); | 200 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
| 201 FixedArray* to = FixedArray::cast(to_base); | 201 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
| 202 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); | 202 ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
| 203 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 203 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 204 Address to_address = to->address() + FixedArray::kHeaderSize; | 204 Address to_address = to->address() + FixedArray::kHeaderSize; |
| 205 Address from_address = from->address() + FixedArray::kHeaderSize; | 205 Address from_address = from->address() + FixedArray::kHeaderSize; |
| 206 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, | 206 CopyWords(reinterpret_cast<Object**>(to_address) + to_start, |
| 207 reinterpret_cast<Object**>(from_address) + from_start, | 207 reinterpret_cast<Object**>(from_address) + from_start, |
| 208 static_cast<size_t>(copy_size)); | 208 static_cast<size_t>(copy_size)); |
| 209 if (IsFastObjectElementsKind(from_kind) && | 209 if (IsFastObjectElementsKind(from_kind) && |
| 210 IsFastObjectElementsKind(to_kind)) { | 210 IsFastObjectElementsKind(to_kind)) { |
| 211 Heap* heap = from->GetHeap(); | 211 Heap* heap = from->GetHeap(); |
| 212 if (!heap->InNewSpace(to)) { | 212 if (!heap->InNewSpace(*to)) { |
| 213 heap->RecordWrites(to->address(), | 213 heap->RecordWrites(to->address(), |
| 214 to->OffsetOfElementAt(to_start), | 214 to->OffsetOfElementAt(to_start), |
| 215 copy_size); | 215 copy_size); |
| 216 } | 216 } |
| 217 heap->incremental_marking()->RecordWrites(to); | 217 heap->incremental_marking()->RecordWrites(*to); |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 static void CopyDictionaryToObjectElements(FixedArrayBase* from_base, | 222 static void CopyDictionaryToObjectElements(Handle<FixedArrayBase> from_base, |
| 223 uint32_t from_start, | 223 uint32_t from_start, |
| 224 FixedArrayBase* to_base, | 224 Handle<FixedArrayBase> to_base, |
| 225 ElementsKind to_kind, | 225 ElementsKind to_kind, |
| 226 uint32_t to_start, | 226 uint32_t to_start, |
| 227 int raw_copy_size) { | 227 int raw_copy_size) { |
| 228 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); | 228 Handle<SeededNumberDictionary> from = |
| 229 Handle<SeededNumberDictionary>::cast(from_base); |
| 229 DisallowHeapAllocation no_allocation; | 230 DisallowHeapAllocation no_allocation; |
| 230 int copy_size = raw_copy_size; | 231 int copy_size = raw_copy_size; |
| 231 Heap* heap = from->GetHeap(); | 232 Heap* heap = from->GetHeap(); |
| 232 if (raw_copy_size < 0) { | 233 if (raw_copy_size < 0) { |
| 233 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 234 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 234 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 235 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 235 copy_size = from->max_number_key() + 1 - from_start; | 236 copy_size = from->max_number_key() + 1 - from_start; |
| 236 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 237 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 237 int start = to_start + copy_size; | 238 int start = to_start + copy_size; |
| 238 int length = to_base->length() - start; | 239 int length = to_base->length() - start; |
| 239 if (length > 0) { | 240 if (length > 0) { |
| 240 Heap* heap = from->GetHeap(); | 241 Heap* heap = from->GetHeap(); |
| 241 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 242 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
| 242 heap->the_hole_value(), length); | 243 heap->the_hole_value(), length); |
| 243 } | 244 } |
| 244 } | 245 } |
| 245 } | 246 } |
| 246 ASSERT(to_base != from_base); | 247 ASSERT(*to_base != *from_base); |
| 247 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 248 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 248 if (copy_size == 0) return; | 249 if (copy_size == 0) return; |
| 249 FixedArray* to = FixedArray::cast(to_base); | 250 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
| 250 uint32_t to_length = to->length(); | 251 uint32_t to_length = to->length(); |
| 251 if (to_start + copy_size > to_length) { | 252 if (to_start + copy_size > to_length) { |
| 252 copy_size = to_length - to_start; | 253 copy_size = to_length - to_start; |
| 253 } | 254 } |
| 254 for (int i = 0; i < copy_size; i++) { | 255 for (int i = 0; i < copy_size; i++) { |
| 255 int entry = from->FindEntry(i + from_start); | 256 int entry = from->FindEntry(i + from_start); |
| 256 if (entry != SeededNumberDictionary::kNotFound) { | 257 if (entry != SeededNumberDictionary::kNotFound) { |
| 257 Object* value = from->ValueAt(entry); | 258 Object* value = from->ValueAt(entry); |
| 258 ASSERT(!value->IsTheHole()); | 259 ASSERT(!value->IsTheHole()); |
| 259 to->set(i + to_start, value, SKIP_WRITE_BARRIER); | 260 to->set(i + to_start, value, SKIP_WRITE_BARRIER); |
| 260 } else { | 261 } else { |
| 261 to->set_the_hole(i + to_start); | 262 to->set_the_hole(i + to_start); |
| 262 } | 263 } |
| 263 } | 264 } |
| 264 if (IsFastObjectElementsKind(to_kind)) { | 265 if (IsFastObjectElementsKind(to_kind)) { |
| 265 if (!heap->InNewSpace(to)) { | 266 if (!heap->InNewSpace(*to)) { |
| 266 heap->RecordWrites(to->address(), | 267 heap->RecordWrites(to->address(), |
| 267 to->OffsetOfElementAt(to_start), | 268 to->OffsetOfElementAt(to_start), |
| 268 copy_size); | 269 copy_size); |
| 269 } | 270 } |
| 270 heap->incremental_marking()->RecordWrites(to); | 271 heap->incremental_marking()->RecordWrites(*to); |
| 271 } | 272 } |
| 272 } | 273 } |
| 273 | 274 |
| 274 | 275 |
| 275 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( | 276 static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base, |
| 276 FixedArrayBase* from_base, | 277 uint32_t from_start, |
| 277 uint32_t from_start, | 278 Handle<FixedArrayBase> to_base, |
| 278 FixedArrayBase* to_base, | 279 ElementsKind to_kind, |
| 279 ElementsKind to_kind, | 280 uint32_t to_start, |
| 280 uint32_t to_start, | 281 int raw_copy_size) { |
| 281 int raw_copy_size) { | |
| 282 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); | 282 ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
| 283 int copy_size = raw_copy_size; | 283 int copy_size = raw_copy_size; |
| 284 if (raw_copy_size < 0) { | 284 if (raw_copy_size < 0) { |
| 285 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 285 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 286 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 286 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 287 copy_size = Min(from_base->length() - from_start, | 287 copy_size = Min(from_base->length() - from_start, |
| 288 to_base->length() - to_start); | 288 to_base->length() - to_start); |
| 289 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 289 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 290 // Also initialize the area that will be copied over since HeapNumber | 290 // Also initialize the area that will be copied over since HeapNumber |
| 291 // allocation below can cause an incremental marking step, requiring all | 291 // allocation below can cause an incremental marking step, requiring all |
| 292 // existing heap objects to be propertly initialized. | 292 // existing heap objects to be propertly initialized. |
| 293 int start = to_start; | 293 int start = to_start; |
| 294 int length = to_base->length() - start; | 294 int length = to_base->length() - start; |
| 295 if (length > 0) { | 295 if (length > 0) { |
| 296 Heap* heap = from_base->GetHeap(); | 296 Heap* heap = from_base->GetHeap(); |
| 297 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 297 MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start, |
| 298 heap->the_hole_value(), length); | 298 heap->the_hole_value(), length); |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 302 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 303 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 303 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 304 if (copy_size == 0) return from_base; | 304 if (copy_size == 0) return; |
| 305 FixedDoubleArray* from = FixedDoubleArray::cast(from_base); | 305 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
| 306 FixedArray* to = FixedArray::cast(to_base); | 306 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
| 307 for (int i = 0; i < copy_size; ++i) { | 307 for (int i = 0; i < copy_size; ++i) { |
| 308 HandleScope scope(from_base->GetIsolate()); |
| 308 if (IsFastSmiElementsKind(to_kind)) { | 309 if (IsFastSmiElementsKind(to_kind)) { |
| 309 UNIMPLEMENTED(); | 310 UNIMPLEMENTED(); |
| 310 return Failure::Exception(); | |
| 311 } else { | 311 } else { |
| 312 MaybeObject* maybe_value = from->get(i + from_start); | |
| 313 Object* value; | |
| 314 ASSERT(IsFastObjectElementsKind(to_kind)); | 312 ASSERT(IsFastObjectElementsKind(to_kind)); |
| 315 // Because Double -> Object elements transitions allocate HeapObjects | 313 Handle<Object> value = from->get_as_handle(i + from_start); |
| 316 // iteratively, the allocate must succeed within a single GC cycle, | 314 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); |
| 317 // otherwise the retry after the GC will also fail. In order to ensure | |
| 318 // that no GC is triggered, allocate HeapNumbers from old space if they | |
| 319 // can't be taken from new space. | |
| 320 if (!maybe_value->ToObject(&value)) { | |
| 321 ASSERT(maybe_value->IsRetryAfterGC()); | |
| 322 Heap* heap = from->GetHeap(); | |
| 323 MaybeObject* maybe_value_object = | |
| 324 heap->AllocateHeapNumber(from->get_scalar(i + from_start), | |
| 325 TENURED); | |
| 326 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; | |
| 327 } | |
| 328 to->set(i + to_start, value, UPDATE_WRITE_BARRIER); | |
| 329 } | 315 } |
| 330 } | 316 } |
| 331 return to; | |
| 332 } | 317 } |
| 333 | 318 |
| 334 | 319 |
| 335 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, | 320 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base, |
| 336 uint32_t from_start, | 321 uint32_t from_start, |
| 337 FixedArrayBase* to_base, | 322 Handle<FixedArrayBase> to_base, |
| 338 uint32_t to_start, | 323 uint32_t to_start, |
| 339 int raw_copy_size) { | 324 int raw_copy_size) { |
| 325 DisallowHeapAllocation no_allocation; |
| 340 int copy_size = raw_copy_size; | 326 int copy_size = raw_copy_size; |
| 341 if (raw_copy_size < 0) { | 327 if (raw_copy_size < 0) { |
| 342 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 328 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 343 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 329 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 344 copy_size = Min(from_base->length() - from_start, | 330 copy_size = Min(from_base->length() - from_start, |
| 345 to_base->length() - to_start); | 331 to_base->length() - to_start); |
| 346 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 332 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 347 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 333 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 348 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 334 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
| 349 } | 335 } |
| 350 } | 336 } |
| 351 } | 337 } |
| 352 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 338 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 353 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 339 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 354 if (copy_size == 0) return; | 340 if (copy_size == 0) return; |
| 355 FixedDoubleArray* from = FixedDoubleArray::cast(from_base); | 341 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
| 356 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 342 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
| 357 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; | 343 Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
| 358 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; | 344 Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
| 359 to_address += kDoubleSize * to_start; | 345 to_address += kDoubleSize * to_start; |
| 360 from_address += kDoubleSize * from_start; | 346 from_address += kDoubleSize * from_start; |
| 361 int words_per_double = (kDoubleSize / kPointerSize); | 347 int words_per_double = (kDoubleSize / kPointerSize); |
| 362 CopyWords(reinterpret_cast<Object**>(to_address), | 348 CopyWords(reinterpret_cast<Object**>(to_address), |
| 363 reinterpret_cast<Object**>(from_address), | 349 reinterpret_cast<Object**>(from_address), |
| 364 static_cast<size_t>(words_per_double * copy_size)); | 350 static_cast<size_t>(words_per_double * copy_size)); |
| 365 } | 351 } |
| 366 | 352 |
| 367 | 353 |
| 368 static void CopySmiToDoubleElements(FixedArrayBase* from_base, | 354 static void CopySmiToDoubleElements(Handle<FixedArrayBase> from_base, |
| 369 uint32_t from_start, | 355 uint32_t from_start, |
| 370 FixedArrayBase* to_base, | 356 Handle<FixedArrayBase> to_base, |
| 371 uint32_t to_start, | 357 uint32_t to_start, |
| 372 int raw_copy_size) { | 358 int raw_copy_size) { |
| 359 DisallowHeapAllocation no_allocation; |
| 373 int copy_size = raw_copy_size; | 360 int copy_size = raw_copy_size; |
| 374 if (raw_copy_size < 0) { | 361 if (raw_copy_size < 0) { |
| 375 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 362 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 376 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 363 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 377 copy_size = from_base->length() - from_start; | 364 copy_size = from_base->length() - from_start; |
| 378 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 365 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 379 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 366 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 380 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 367 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
| 381 } | 368 } |
| 382 } | 369 } |
| 383 } | 370 } |
| 384 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 371 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 385 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 372 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 386 if (copy_size == 0) return; | 373 if (copy_size == 0) return; |
| 387 FixedArray* from = FixedArray::cast(from_base); | 374 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
| 388 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 375 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
| 389 Object* the_hole = from->GetHeap()->the_hole_value(); | 376 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); |
| 390 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); | 377 for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
| 391 from_start < from_end; from_start++, to_start++) { | 378 from_start < from_end; from_start++, to_start++) { |
| 392 Object* hole_or_smi = from->get(from_start); | 379 Object* hole_or_smi = from->get(from_start); |
| 393 if (hole_or_smi == the_hole) { | 380 if (hole_or_smi == *the_hole) { |
| 394 to->set_the_hole(to_start); | 381 to->set_the_hole(to_start); |
| 395 } else { | 382 } else { |
| 396 to->set(to_start, Smi::cast(hole_or_smi)->value()); | 383 to->set(to_start, Smi::cast(hole_or_smi)->value()); |
| 397 } | 384 } |
| 398 } | 385 } |
| 399 } | 386 } |
| 400 | 387 |
| 401 | 388 |
| 402 static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, | 389 static void CopyPackedSmiToDoubleElements(Handle<FixedArrayBase> from_base, |
| 403 uint32_t from_start, | 390 uint32_t from_start, |
| 404 FixedArrayBase* to_base, | 391 Handle<FixedArrayBase> to_base, |
| 405 uint32_t to_start, | 392 uint32_t to_start, |
| 406 int packed_size, | 393 int packed_size, |
| 407 int raw_copy_size) { | 394 int raw_copy_size) { |
| 395 DisallowHeapAllocation no_allocation; |
| 408 int copy_size = raw_copy_size; | 396 int copy_size = raw_copy_size; |
| 409 uint32_t to_end; | 397 uint32_t to_end; |
| 410 if (raw_copy_size < 0) { | 398 if (raw_copy_size < 0) { |
| 411 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 399 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 412 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 400 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 413 copy_size = packed_size - from_start; | 401 copy_size = packed_size - from_start; |
| 414 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 402 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 415 to_end = to_base->length(); | 403 to_end = to_base->length(); |
| 416 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { | 404 for (uint32_t i = to_start + copy_size; i < to_end; ++i) { |
| 417 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 405 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
| 418 } | 406 } |
| 419 } else { | 407 } else { |
| 420 to_end = to_start + static_cast<uint32_t>(copy_size); | 408 to_end = to_start + static_cast<uint32_t>(copy_size); |
| 421 } | 409 } |
| 422 } else { | 410 } else { |
| 423 to_end = to_start + static_cast<uint32_t>(copy_size); | 411 to_end = to_start + static_cast<uint32_t>(copy_size); |
| 424 } | 412 } |
| 425 ASSERT(static_cast<int>(to_end) <= to_base->length()); | 413 ASSERT(static_cast<int>(to_end) <= to_base->length()); |
| 426 ASSERT(packed_size >= 0 && packed_size <= copy_size); | 414 ASSERT(packed_size >= 0 && packed_size <= copy_size); |
| 427 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 415 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 428 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 416 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 429 if (copy_size == 0) return; | 417 if (copy_size == 0) return; |
| 430 FixedArray* from = FixedArray::cast(from_base); | 418 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
| 431 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 419 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
| 432 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); | 420 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
| 433 from_start < from_end; from_start++, to_start++) { | 421 from_start < from_end; from_start++, to_start++) { |
| 434 Object* smi = from->get(from_start); | 422 Object* smi = from->get(from_start); |
| 435 ASSERT(!smi->IsTheHole()); | 423 ASSERT(!smi->IsTheHole()); |
| 436 to->set(to_start, Smi::cast(smi)->value()); | 424 to->set(to_start, Smi::cast(smi)->value()); |
| 437 } | 425 } |
| 438 } | 426 } |
| 439 | 427 |
| 440 | 428 |
| 441 static void CopyObjectToDoubleElements(FixedArrayBase* from_base, | 429 static void CopyObjectToDoubleElements(Handle<FixedArrayBase> from_base, |
| 442 uint32_t from_start, | 430 uint32_t from_start, |
| 443 FixedArrayBase* to_base, | 431 Handle<FixedArrayBase> to_base, |
| 444 uint32_t to_start, | 432 uint32_t to_start, |
| 445 int raw_copy_size) { | 433 int raw_copy_size) { |
| 434 DisallowHeapAllocation no_allocation; |
| 446 int copy_size = raw_copy_size; | 435 int copy_size = raw_copy_size; |
| 447 if (raw_copy_size < 0) { | 436 if (raw_copy_size < 0) { |
| 448 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || | 437 ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
| 449 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 438 raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 450 copy_size = from_base->length() - from_start; | 439 copy_size = from_base->length() - from_start; |
| 451 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 440 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 452 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 441 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 453 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 442 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
| 454 } | 443 } |
| 455 } | 444 } |
| 456 } | 445 } |
| 457 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 446 ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 458 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 447 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 459 if (copy_size == 0) return; | 448 if (copy_size == 0) return; |
| 460 FixedArray* from = FixedArray::cast(from_base); | 449 Handle<FixedArray> from = Handle<FixedArray>::cast(from_base); |
| 461 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 450 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
| 462 Object* the_hole = from->GetHeap()->the_hole_value(); | 451 Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value(); |
| 463 for (uint32_t from_end = from_start + copy_size; | 452 for (uint32_t from_end = from_start + copy_size; |
| 464 from_start < from_end; from_start++, to_start++) { | 453 from_start < from_end; from_start++, to_start++) { |
| 465 Object* hole_or_object = from->get(from_start); | 454 Object* hole_or_object = from->get(from_start); |
| 466 if (hole_or_object == the_hole) { | 455 if (hole_or_object == *the_hole) { |
| 467 to->set_the_hole(to_start); | 456 to->set_the_hole(to_start); |
| 468 } else { | 457 } else { |
| 469 to->set(to_start, hole_or_object->Number()); | 458 to->set(to_start, hole_or_object->Number()); |
| 470 } | 459 } |
| 471 } | 460 } |
| 472 } | 461 } |
| 473 | 462 |
| 474 | 463 |
| 475 static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, | 464 static void CopyDictionaryToDoubleElements(Handle<FixedArrayBase> from_base, |
| 476 uint32_t from_start, | 465 uint32_t from_start, |
| 477 FixedArrayBase* to_base, | 466 Handle<FixedArrayBase> to_base, |
| 478 uint32_t to_start, | 467 uint32_t to_start, |
| 479 int raw_copy_size) { | 468 int raw_copy_size) { |
| 480 SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); | 469 Handle<SeededNumberDictionary> from = |
| 470 Handle<SeededNumberDictionary>::cast(from_base); |
| 471 DisallowHeapAllocation no_allocation; |
| 481 int copy_size = raw_copy_size; | 472 int copy_size = raw_copy_size; |
| 482 if (copy_size < 0) { | 473 if (copy_size < 0) { |
| 483 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || | 474 ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
| 484 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); | 475 copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 485 copy_size = from->max_number_key() + 1 - from_start; | 476 copy_size = from->max_number_key() + 1 - from_start; |
| 486 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { | 477 if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
| 487 for (int i = to_start + copy_size; i < to_base->length(); ++i) { | 478 for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
| 488 FixedDoubleArray::cast(to_base)->set_the_hole(i); | 479 Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i); |
| 489 } | 480 } |
| 490 } | 481 } |
| 491 } | 482 } |
| 492 if (copy_size == 0) return; | 483 if (copy_size == 0) return; |
| 493 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 484 Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base); |
| 494 uint32_t to_length = to->length(); | 485 uint32_t to_length = to->length(); |
| 495 if (to_start + copy_size > to_length) { | 486 if (to_start + copy_size > to_length) { |
| 496 copy_size = to_length - to_start; | 487 copy_size = to_length - to_start; |
| 497 } | 488 } |
| 498 for (int i = 0; i < copy_size; i++) { | 489 for (int i = 0; i < copy_size; i++) { |
| 499 int entry = from->FindEntry(i + from_start); | 490 int entry = from->FindEntry(i + from_start); |
| 500 if (entry != SeededNumberDictionary::kNotFound) { | 491 if (entry != SeededNumberDictionary::kNotFound) { |
| 501 to->set(i + to_start, from->ValueAt(entry)->Number()); | 492 to->set(i + to_start, from->ValueAt(entry)->Number()); |
| 502 } else { | 493 } else { |
| 503 to->set_the_hole(i + to_start); | 494 to->set_the_hole(i + to_start); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 Object* receiver, | 740 Object* receiver, |
| 750 JSObject* obj, | 741 JSObject* obj, |
| 751 uint32_t key, | 742 uint32_t key, |
| 752 FixedArrayBase* backing_store) { | 743 FixedArrayBase* backing_store) { |
| 753 return NULL; | 744 return NULL; |
| 754 } | 745 } |
| 755 | 746 |
| 756 MUST_USE_RESULT virtual Handle<Object> SetLength( | 747 MUST_USE_RESULT virtual Handle<Object> SetLength( |
| 757 Handle<JSArray> array, | 748 Handle<JSArray> array, |
| 758 Handle<Object> length) V8_FINAL V8_OVERRIDE { | 749 Handle<Object> length) V8_FINAL V8_OVERRIDE { |
| 759 Isolate* isolate = array->GetIsolate(); | |
| 760 return ElementsAccessorSubclass::SetLengthImpl( | 750 return ElementsAccessorSubclass::SetLengthImpl( |
| 761 array, length, handle(array->elements(), isolate)); | 751 array, length, handle(array->elements())); |
| 762 } | 752 } |
| 763 | 753 |
| 764 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 754 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
| 765 Handle<JSObject> obj, | 755 Handle<JSObject> obj, |
| 766 Handle<Object> length, | 756 Handle<Object> length, |
| 767 Handle<FixedArrayBase> backing_store); | 757 Handle<FixedArrayBase> backing_store); |
| 768 | 758 |
| 769 virtual void SetCapacityAndLength( | 759 virtual void SetCapacityAndLength( |
| 770 Handle<JSArray> array, | 760 Handle<JSArray> array, |
| 771 int capacity, | 761 int capacity, |
| 772 int length) V8_FINAL V8_OVERRIDE { | 762 int length) V8_FINAL V8_OVERRIDE { |
| 773 ElementsAccessorSubclass:: | 763 ElementsAccessorSubclass:: |
| 774 SetFastElementsCapacityAndLength(array, capacity, length); | 764 SetFastElementsCapacityAndLength(array, capacity, length); |
| 775 } | 765 } |
| 776 | 766 |
| 777 static void SetFastElementsCapacityAndLength( | 767 static void SetFastElementsCapacityAndLength( |
| 778 Handle<JSObject> obj, | 768 Handle<JSObject> obj, |
| 779 int capacity, | 769 int capacity, |
| 780 int length) { | 770 int length) { |
| 781 UNIMPLEMENTED(); | 771 UNIMPLEMENTED(); |
| 782 } | 772 } |
| 783 | 773 |
| 784 MUST_USE_RESULT virtual Handle<Object> Delete( | 774 MUST_USE_RESULT virtual Handle<Object> Delete( |
| 785 Handle<JSObject> obj, | 775 Handle<JSObject> obj, |
| 786 uint32_t key, | 776 uint32_t key, |
| 787 JSReceiver::DeleteMode mode) V8_OVERRIDE = 0; | 777 JSReceiver::DeleteMode mode) V8_OVERRIDE = 0; |
| 788 | 778 |
| 789 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 779 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 790 uint32_t from_start, | 780 uint32_t from_start, |
| 791 FixedArrayBase* to, | 781 Handle<FixedArrayBase> to, |
| 792 ElementsKind from_kind, | 782 ElementsKind from_kind, |
| 793 uint32_t to_start, | 783 uint32_t to_start, |
| 794 int packed_size, | 784 int packed_size, |
| 795 int copy_size) { | 785 int copy_size) { |
| 796 UNREACHABLE(); | 786 UNREACHABLE(); |
| 797 return NULL; | |
| 798 } | |
| 799 | |
| 800 // TODO(ishell): Temporary wrapper, remove when CopyElements handlified. | |
| 801 Handle<Object> CopyElementsHelper( | |
| 802 Handle<JSObject> from_holder, | |
| 803 uint32_t from_start, | |
| 804 ElementsKind from_kind, | |
| 805 Handle<FixedArrayBase> to, | |
| 806 uint32_t to_start, | |
| 807 int copy_size, | |
| 808 Handle<FixedArrayBase> from) { | |
| 809 CALL_HEAP_FUNCTION(to->GetIsolate(), | |
| 810 CopyElements( | |
| 811 from_holder.is_null() ? NULL : *from_holder, | |
| 812 from_start, from_kind, *to, to_start, copy_size, | |
| 813 from.is_null() ? NULL : *from), | |
| 814 Object); | |
| 815 } | 787 } |
| 816 | 788 |
| 817 virtual void CopyElements( | 789 virtual void CopyElements( |
| 818 Handle<JSObject> from_holder, | 790 Handle<JSObject> from_holder, |
| 819 uint32_t from_start, | 791 uint32_t from_start, |
| 820 ElementsKind from_kind, | 792 ElementsKind from_kind, |
| 821 Handle<FixedArrayBase> to, | 793 Handle<FixedArrayBase> to, |
| 822 uint32_t to_start, | 794 uint32_t to_start, |
| 823 int copy_size, | 795 int copy_size, |
| 824 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { | 796 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { |
| 825 Handle<Object> result = CopyElementsHelper( | |
| 826 from_holder, from_start, from_kind, to, to_start, copy_size, from); | |
| 827 ASSERT(!result.is_null()); | |
| 828 USE(result); | |
| 829 } | |
| 830 | |
| 831 MUST_USE_RESULT virtual MaybeObject* CopyElements( | |
| 832 JSObject* from_holder, | |
| 833 uint32_t from_start, | |
| 834 ElementsKind from_kind, | |
| 835 FixedArrayBase* to, | |
| 836 uint32_t to_start, | |
| 837 int copy_size, | |
| 838 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { | |
| 839 int packed_size = kPackedSizeNotKnown; | 797 int packed_size = kPackedSizeNotKnown; |
| 840 if (from == NULL) { | 798 if (from.is_null()) { |
| 841 from = from_holder->elements(); | 799 from = handle(from_holder->elements()); |
| 842 } | 800 } |
| 843 | 801 |
| 844 if (from_holder) { | 802 if (!from_holder.is_null()) { |
| 845 bool is_packed = IsFastPackedElementsKind(from_kind) && | 803 bool is_packed = IsFastPackedElementsKind(from_kind) && |
| 846 from_holder->IsJSArray(); | 804 from_holder->IsJSArray(); |
| 847 if (is_packed) { | 805 if (is_packed) { |
| 848 packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value(); | 806 packed_size = |
| 807 Smi::cast(Handle<JSArray>::cast(from_holder)->length())->value(); |
| 849 if (copy_size >= 0 && packed_size > copy_size) { | 808 if (copy_size >= 0 && packed_size > copy_size) { |
| 850 packed_size = copy_size; | 809 packed_size = copy_size; |
| 851 } | 810 } |
| 852 } | 811 } |
| 853 } | 812 } |
| 854 return ElementsAccessorSubclass::CopyElementsImpl( | 813 ElementsAccessorSubclass::CopyElementsImpl( |
| 855 from, from_start, to, from_kind, to_start, packed_size, copy_size); | 814 from, from_start, to, from_kind, to_start, packed_size, copy_size); |
| 856 } | 815 } |
| 857 | 816 |
| 858 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( | 817 MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( |
| 859 Object* receiver, | 818 Object* receiver, |
| 860 JSObject* holder, | 819 JSObject* holder, |
| 861 FixedArray* to, | 820 FixedArray* to, |
| 862 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { | 821 FixedArrayBase* from) V8_FINAL V8_OVERRIDE { |
| 863 int len0 = to->length(); | 822 int len0 = to->length(); |
| 864 #ifdef ENABLE_SLOW_ASSERTS | 823 #ifdef ENABLE_SLOW_ASSERTS |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 } | 993 } |
| 1035 | 994 |
| 1036 static Handle<Object> DeleteCommon(Handle<JSObject> obj, | 995 static Handle<Object> DeleteCommon(Handle<JSObject> obj, |
| 1037 uint32_t key, | 996 uint32_t key, |
| 1038 JSReceiver::DeleteMode mode) { | 997 JSReceiver::DeleteMode mode) { |
| 1039 ASSERT(obj->HasFastSmiOrObjectElements() || | 998 ASSERT(obj->HasFastSmiOrObjectElements() || |
| 1040 obj->HasFastDoubleElements() || | 999 obj->HasFastDoubleElements() || |
| 1041 obj->HasFastArgumentsElements()); | 1000 obj->HasFastArgumentsElements()); |
| 1042 Isolate* isolate = obj->GetIsolate(); | 1001 Isolate* isolate = obj->GetIsolate(); |
| 1043 Heap* heap = obj->GetHeap(); | 1002 Heap* heap = obj->GetHeap(); |
| 1044 Handle<Object> elements = handle(obj->elements(), isolate); | 1003 Handle<FixedArrayBase> elements(obj->elements()); |
| 1045 if (*elements == heap->empty_fixed_array()) { | 1004 if (*elements == heap->empty_fixed_array()) { |
| 1046 return isolate->factory()->true_value(); | 1005 return isolate->factory()->true_value(); |
| 1047 } | 1006 } |
| 1048 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1007 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
| 1049 bool is_sloppy_arguments_elements_map = | 1008 bool is_sloppy_arguments_elements_map = |
| 1050 backing_store->map() == heap->sloppy_arguments_elements_map(); | 1009 backing_store->map() == heap->sloppy_arguments_elements_map(); |
| 1051 if (is_sloppy_arguments_elements_map) { | 1010 if (is_sloppy_arguments_elements_map) { |
| 1052 backing_store = Handle<BackingStore>::cast( | 1011 backing_store = handle( |
| 1053 handle(Handle<FixedArray>::cast(backing_store)->get(1), isolate)); | 1012 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1))); |
| 1054 } | 1013 } |
| 1055 uint32_t length = static_cast<uint32_t>( | 1014 uint32_t length = static_cast<uint32_t>( |
| 1056 obj->IsJSArray() | 1015 obj->IsJSArray() |
| 1057 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() | 1016 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() |
| 1058 : backing_store->length()); | 1017 : backing_store->length()); |
| 1059 if (key < length) { | 1018 if (key < length) { |
| 1060 if (!is_sloppy_arguments_elements_map) { | 1019 if (!is_sloppy_arguments_elements_map) { |
| 1061 ElementsKind kind = KindTraits::Kind; | 1020 ElementsKind kind = KindTraits::Kind; |
| 1062 if (IsFastPackedElementsKind(kind)) { | 1021 if (IsFastPackedElementsKind(kind)) { |
| 1063 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | 1022 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 FixedArrayBase* elements = holder->elements(); | 1073 FixedArrayBase* elements = holder->elements(); |
| 1115 Heap* heap = elements->GetHeap(); | 1074 Heap* heap = elements->GetHeap(); |
| 1116 Map* map = elements->map(); | 1075 Map* map = elements->map(); |
| 1117 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 1076 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && |
| 1118 (map == heap->fixed_array_map() || | 1077 (map == heap->fixed_array_map() || |
| 1119 map == heap->fixed_cow_array_map())) || | 1078 map == heap->fixed_cow_array_map())) || |
| 1120 (IsFastDoubleElementsKind(KindTraits::Kind) == | 1079 (IsFastDoubleElementsKind(KindTraits::Kind) == |
| 1121 ((map == heap->fixed_array_map() && length == 0) || | 1080 ((map == heap->fixed_array_map() && length == 0) || |
| 1122 map == heap->fixed_double_array_map()))); | 1081 map == heap->fixed_double_array_map()))); |
| 1123 for (int i = 0; i < length; i++) { | 1082 for (int i = 0; i < length; i++) { |
| 1124 typename KindTraits::BackingStore* backing_store = | 1083 BackingStore* backing_store = BackingStore::cast(elements); |
| 1125 KindTraits::BackingStore::cast(elements); | |
| 1126 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || | 1084 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || |
| 1127 static_cast<Object*>(backing_store->get(i))->IsSmi()) || | 1085 static_cast<Object*>(backing_store->get(i))->IsSmi()) || |
| 1128 (IsFastHoleyElementsKind(KindTraits::Kind) == | 1086 (IsFastHoleyElementsKind(KindTraits::Kind) == |
| 1129 backing_store->is_the_hole(i))); | 1087 backing_store->is_the_hole(i))); |
| 1130 } | 1088 } |
| 1131 #endif | 1089 #endif |
| 1132 } | 1090 } |
| 1133 }; | 1091 }; |
| 1134 | 1092 |
| 1135 | 1093 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1165 class FastSmiOrObjectElementsAccessor | 1123 class FastSmiOrObjectElementsAccessor |
| 1166 : public FastElementsAccessor<FastElementsAccessorSubclass, | 1124 : public FastElementsAccessor<FastElementsAccessorSubclass, |
| 1167 KindTraits, | 1125 KindTraits, |
| 1168 kPointerSize> { | 1126 kPointerSize> { |
| 1169 public: | 1127 public: |
| 1170 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1128 explicit FastSmiOrObjectElementsAccessor(const char* name) |
| 1171 : FastElementsAccessor<FastElementsAccessorSubclass, | 1129 : FastElementsAccessor<FastElementsAccessorSubclass, |
| 1172 KindTraits, | 1130 KindTraits, |
| 1173 kPointerSize>(name) {} | 1131 kPointerSize>(name) {} |
| 1174 | 1132 |
| 1175 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1133 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 1176 uint32_t from_start, | 1134 uint32_t from_start, |
| 1177 FixedArrayBase* to, | 1135 Handle<FixedArrayBase> to, |
| 1178 ElementsKind from_kind, | 1136 ElementsKind from_kind, |
| 1179 uint32_t to_start, | 1137 uint32_t to_start, |
| 1180 int packed_size, | 1138 int packed_size, |
| 1181 int copy_size) { | 1139 int copy_size) { |
| 1182 ElementsKind to_kind = KindTraits::Kind; | 1140 ElementsKind to_kind = KindTraits::Kind; |
| 1183 switch (from_kind) { | 1141 switch (from_kind) { |
| 1184 case FAST_SMI_ELEMENTS: | 1142 case FAST_SMI_ELEMENTS: |
| 1185 case FAST_HOLEY_SMI_ELEMENTS: | 1143 case FAST_HOLEY_SMI_ELEMENTS: |
| 1186 case FAST_ELEMENTS: | 1144 case FAST_ELEMENTS: |
| 1187 case FAST_HOLEY_ELEMENTS: | 1145 case FAST_HOLEY_ELEMENTS: |
| 1188 CopyObjectToObjectElements( | 1146 CopyObjectToObjectElements( |
| 1189 from, from_kind, from_start, to, to_kind, to_start, copy_size); | 1147 from, from_kind, from_start, to, to_kind, to_start, copy_size); |
| 1190 return to->GetHeap()->undefined_value(); | 1148 break; |
| 1191 case FAST_DOUBLE_ELEMENTS: | 1149 case FAST_DOUBLE_ELEMENTS: |
| 1192 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1150 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 1193 return CopyDoubleToObjectElements( | 1151 CopyDoubleToObjectElements( |
| 1194 from, from_start, to, to_kind, to_start, copy_size); | 1152 from, from_start, to, to_kind, to_start, copy_size); |
| 1153 break; |
| 1195 case DICTIONARY_ELEMENTS: | 1154 case DICTIONARY_ELEMENTS: |
| 1196 CopyDictionaryToObjectElements( | 1155 CopyDictionaryToObjectElements( |
| 1197 from, from_start, to, to_kind, to_start, copy_size); | 1156 from, from_start, to, to_kind, to_start, copy_size); |
| 1198 return to->GetHeap()->undefined_value(); | 1157 break; |
| 1199 case SLOPPY_ARGUMENTS_ELEMENTS: { | 1158 case SLOPPY_ARGUMENTS_ELEMENTS: { |
| 1200 // TODO(verwaest): This is a temporary hack to support extending | 1159 // TODO(verwaest): This is a temporary hack to support extending |
| 1201 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. | 1160 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
| 1202 // This case should be UNREACHABLE(). | 1161 // This case should be UNREACHABLE(). |
| 1203 FixedArray* parameter_map = FixedArray::cast(from); | 1162 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); |
| 1204 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1163 Handle<FixedArrayBase> arguments( |
| 1205 ElementsKind from_kind = ElementsKindForArray(arguments); | 1164 FixedArrayBase::cast(parameter_map->get(1))); |
| 1206 return CopyElementsImpl(arguments, from_start, to, from_kind, | 1165 ElementsKind from_kind = ElementsKindForArray(*arguments); |
| 1207 to_start, packed_size, copy_size); | 1166 CopyElementsImpl(arguments, from_start, to, from_kind, |
| 1167 to_start, packed_size, copy_size); |
| 1168 break; |
| 1208 } | 1169 } |
| 1209 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1170 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 1210 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1171 case EXTERNAL_##TYPE##_ELEMENTS: \ |
| 1211 case TYPE##_ELEMENTS: \ | 1172 case TYPE##_ELEMENTS: \ |
| 1212 UNREACHABLE(); | 1173 UNREACHABLE(); |
| 1213 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1174 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 1214 #undef TYPED_ARRAY_CASE | 1175 #undef TYPED_ARRAY_CASE |
| 1215 } | 1176 } |
| 1216 return NULL; | |
| 1217 } | 1177 } |
| 1218 | 1178 |
| 1219 | 1179 |
| 1220 static void SetFastElementsCapacityAndLength( | 1180 static void SetFastElementsCapacityAndLength( |
| 1221 Handle<JSObject> obj, | 1181 Handle<JSObject> obj, |
| 1222 uint32_t capacity, | 1182 uint32_t capacity, |
| 1223 uint32_t length) { | 1183 uint32_t length) { |
| 1224 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = | 1184 JSObject::SetFastElementsCapacitySmiMode set_capacity_mode = |
| 1225 obj->HasFastSmiElements() | 1185 obj->HasFastSmiElements() |
| 1226 ? JSObject::kAllowSmiElements | 1186 ? JSObject::kAllowSmiElements |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 KindTraits, | 1251 KindTraits, |
| 1292 kDoubleSize>(name) {} | 1252 kDoubleSize>(name) {} |
| 1293 | 1253 |
| 1294 static void SetFastElementsCapacityAndLength(Handle<JSObject> obj, | 1254 static void SetFastElementsCapacityAndLength(Handle<JSObject> obj, |
| 1295 uint32_t capacity, | 1255 uint32_t capacity, |
| 1296 uint32_t length) { | 1256 uint32_t length) { |
| 1297 JSObject::SetFastDoubleElementsCapacityAndLength(obj, capacity, length); | 1257 JSObject::SetFastDoubleElementsCapacityAndLength(obj, capacity, length); |
| 1298 } | 1258 } |
| 1299 | 1259 |
| 1300 protected: | 1260 protected: |
| 1301 static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1261 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 1302 uint32_t from_start, | 1262 uint32_t from_start, |
| 1303 FixedArrayBase* to, | 1263 Handle<FixedArrayBase> to, |
| 1304 ElementsKind from_kind, | 1264 ElementsKind from_kind, |
| 1305 uint32_t to_start, | 1265 uint32_t to_start, |
| 1306 int packed_size, | 1266 int packed_size, |
| 1307 int copy_size) { | 1267 int copy_size) { |
| 1308 switch (from_kind) { | 1268 switch (from_kind) { |
| 1309 case FAST_SMI_ELEMENTS: | 1269 case FAST_SMI_ELEMENTS: |
| 1310 CopyPackedSmiToDoubleElements( | 1270 CopyPackedSmiToDoubleElements( |
| 1311 from, from_start, to, to_start, packed_size, copy_size); | 1271 from, from_start, to, to_start, packed_size, copy_size); |
| 1312 break; | 1272 break; |
| 1313 case FAST_HOLEY_SMI_ELEMENTS: | 1273 case FAST_HOLEY_SMI_ELEMENTS: |
| 1314 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); | 1274 CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); |
| 1315 break; | 1275 break; |
| 1316 case FAST_DOUBLE_ELEMENTS: | 1276 case FAST_DOUBLE_ELEMENTS: |
| 1317 case FAST_HOLEY_DOUBLE_ELEMENTS: | 1277 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1328 case SLOPPY_ARGUMENTS_ELEMENTS: | 1288 case SLOPPY_ARGUMENTS_ELEMENTS: |
| 1329 UNREACHABLE(); | 1289 UNREACHABLE(); |
| 1330 | 1290 |
| 1331 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1291 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 1332 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1292 case EXTERNAL_##TYPE##_ELEMENTS: \ |
| 1333 case TYPE##_ELEMENTS: \ | 1293 case TYPE##_ELEMENTS: \ |
| 1334 UNREACHABLE(); | 1294 UNREACHABLE(); |
| 1335 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1295 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 1336 #undef TYPED_ARRAY_CASE | 1296 #undef TYPED_ARRAY_CASE |
| 1337 } | 1297 } |
| 1338 return to->GetHeap()->undefined_value(); | |
| 1339 } | 1298 } |
| 1340 }; | 1299 }; |
| 1341 | 1300 |
| 1342 | 1301 |
| 1343 class FastPackedDoubleElementsAccessor | 1302 class FastPackedDoubleElementsAccessor |
| 1344 : public FastDoubleElementsAccessor< | 1303 : public FastDoubleElementsAccessor< |
| 1345 FastPackedDoubleElementsAccessor, | 1304 FastPackedDoubleElementsAccessor, |
| 1346 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { | 1305 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { |
| 1347 public: | 1306 public: |
| 1348 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor, | 1307 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor, |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1588 // TODO(ishell): Temporary wrapper until handlified. | 1547 // TODO(ishell): Temporary wrapper until handlified. |
| 1589 MUST_USE_RESULT static Handle<Object> DeleteCommon( | 1548 MUST_USE_RESULT static Handle<Object> DeleteCommon( |
| 1590 Handle<JSObject> obj, | 1549 Handle<JSObject> obj, |
| 1591 uint32_t key, | 1550 uint32_t key, |
| 1592 JSReceiver::DeleteMode mode) { | 1551 JSReceiver::DeleteMode mode) { |
| 1593 CALL_HEAP_FUNCTION(obj->GetIsolate(), | 1552 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 1594 DeleteCommon(*obj, key, mode), | 1553 DeleteCommon(*obj, key, mode), |
| 1595 Object); | 1554 Object); |
| 1596 } | 1555 } |
| 1597 | 1556 |
| 1598 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1557 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 1599 uint32_t from_start, | 1558 uint32_t from_start, |
| 1600 FixedArrayBase* to, | 1559 Handle<FixedArrayBase> to, |
| 1601 ElementsKind from_kind, | 1560 ElementsKind from_kind, |
| 1602 uint32_t to_start, | 1561 uint32_t to_start, |
| 1603 int packed_size, | 1562 int packed_size, |
| 1604 int copy_size) { | 1563 int copy_size) { |
| 1605 UNREACHABLE(); | 1564 UNREACHABLE(); |
| 1606 return NULL; | |
| 1607 } | 1565 } |
| 1608 | 1566 |
| 1609 | 1567 |
| 1610 protected: | 1568 protected: |
| 1611 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1569 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 1612 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1570 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
| 1613 | 1571 |
| 1614 MUST_USE_RESULT virtual Handle<Object> Delete( | 1572 MUST_USE_RESULT virtual Handle<Object> Delete( |
| 1615 Handle<JSObject> obj, | 1573 Handle<JSObject> obj, |
| 1616 uint32_t key, | 1574 uint32_t key, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 // correctly implement [[DefineOwnProperty]] on arrays. | 1760 // correctly implement [[DefineOwnProperty]] on arrays. |
| 1803 UNIMPLEMENTED(); | 1761 UNIMPLEMENTED(); |
| 1804 return obj; | 1762 return obj; |
| 1805 } | 1763 } |
| 1806 | 1764 |
| 1807 MUST_USE_RESULT virtual Handle<Object> Delete( | 1765 MUST_USE_RESULT virtual Handle<Object> Delete( |
| 1808 Handle<JSObject> obj, | 1766 Handle<JSObject> obj, |
| 1809 uint32_t key, | 1767 uint32_t key, |
| 1810 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1768 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
| 1811 Isolate* isolate = obj->GetIsolate(); | 1769 Isolate* isolate = obj->GetIsolate(); |
| 1812 Handle<FixedArray> parameter_map = | 1770 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
| 1813 handle(FixedArray::cast(obj->elements()), isolate); | |
| 1814 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1771 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
| 1815 if (!probe->IsTheHole()) { | 1772 if (!probe->IsTheHole()) { |
| 1816 // TODO(kmillikin): We could check if this was the last aliased | 1773 // TODO(kmillikin): We could check if this was the last aliased |
| 1817 // parameter, and revert to normal elements in that case. That | 1774 // parameter, and revert to normal elements in that case. That |
| 1818 // would enable GC of the context. | 1775 // would enable GC of the context. |
| 1819 parameter_map->set_the_hole(key + 2); | 1776 parameter_map->set_the_hole(key + 2); |
| 1820 } else { | 1777 } else { |
| 1821 Handle<FixedArray> arguments = | 1778 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 1822 handle(FixedArray::cast(parameter_map->get(1)), isolate); | |
| 1823 if (arguments->IsDictionary()) { | 1779 if (arguments->IsDictionary()) { |
| 1824 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); | 1780 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); |
| 1825 } else { | 1781 } else { |
| 1826 // It's difficult to access the version of DeleteCommon that is declared | 1782 // It's difficult to access the version of DeleteCommon that is declared |
| 1827 // in the templatized super class, call the concrete implementation in | 1783 // in the templatized super class, call the concrete implementation in |
| 1828 // the class for the most generalized ElementsKind subclass. | 1784 // the class for the most generalized ElementsKind subclass. |
| 1829 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); | 1785 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); |
| 1830 } | 1786 } |
| 1831 } | 1787 } |
| 1832 return isolate->factory()->true_value(); | 1788 return isolate->factory()->true_value(); |
| 1833 } | 1789 } |
| 1834 | 1790 |
| 1835 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1791 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
| 1836 uint32_t from_start, | 1792 uint32_t from_start, |
| 1837 FixedArrayBase* to, | 1793 Handle<FixedArrayBase> to, |
| 1838 ElementsKind from_kind, | 1794 ElementsKind from_kind, |
| 1839 uint32_t to_start, | 1795 uint32_t to_start, |
| 1840 int packed_size, | 1796 int packed_size, |
| 1841 int copy_size) { | 1797 int copy_size) { |
| 1842 UNREACHABLE(); | 1798 UNREACHABLE(); |
| 1843 return NULL; | |
| 1844 } | 1799 } |
| 1845 | 1800 |
| 1846 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { | 1801 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
| 1847 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1802 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 1848 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1803 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 1849 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1804 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
| 1850 ForArray(arguments)->GetCapacity(arguments)); | 1805 ForArray(arguments)->GetCapacity(arguments)); |
| 1851 } | 1806 } |
| 1852 | 1807 |
| 1853 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, | 1808 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 UNREACHABLE(); | 2033 UNREACHABLE(); |
| 2079 break; | 2034 break; |
| 2080 } | 2035 } |
| 2081 | 2036 |
| 2082 array->set_elements(*elms); | 2037 array->set_elements(*elms); |
| 2083 array->set_length(Smi::FromInt(number_of_elements)); | 2038 array->set_length(Smi::FromInt(number_of_elements)); |
| 2084 return array; | 2039 return array; |
| 2085 } | 2040 } |
| 2086 | 2041 |
| 2087 } } // namespace v8::internal | 2042 } } // namespace v8::internal |
| OLD | NEW |