Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 9365020: Convert fast smi-only to fast object in generated code for array push. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 1338 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
1339 name, &miss); 1339 name, &miss);
1340 1340
1341 if (argc == 0) { 1341 if (argc == 0) {
1342 // Noop, return the length. 1342 // Noop, return the length.
1343 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1343 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1344 __ ret((argc + 1) * kPointerSize); 1344 __ ret((argc + 1) * kPointerSize);
1345 } else { 1345 } else {
1346 Label call_builtin; 1346 Label call_builtin;
1347 1347
1348 // Get the elements array of the object.
1349 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1350
1351 // Check that the elements are in fast mode and writable.
1352 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1353 Immediate(factory()->fixed_array_map()));
1354 __ j(not_equal, &call_builtin);
1355
1356 if (argc == 1) { // Otherwise fall through to call builtin. 1348 if (argc == 1) { // Otherwise fall through to call builtin.
1357 Label attempt_to_grow_elements, with_write_barrier; 1349 Label attempt_to_grow_elements, with_write_barrier;
1358 1350
1351 // Get the elements array of the object.
1352 __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
1353
1354 // Check that the elements are in fast mode and writable.
1355 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
1356 Immediate(factory()->fixed_array_map()));
1357 __ j(not_equal, &call_builtin);
1358
1359 // Get the array's length into eax and calculate new length. 1359 // Get the array's length into eax and calculate new length.
1360 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1360 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1361 STATIC_ASSERT(kSmiTagSize == 1); 1361 STATIC_ASSERT(kSmiTagSize == 1);
1362 STATIC_ASSERT(kSmiTag == 0); 1362 STATIC_ASSERT(kSmiTag == 0);
1363 __ add(eax, Immediate(Smi::FromInt(argc))); 1363 __ add(eax, Immediate(Smi::FromInt(argc)));
1364 1364
1365 // Get the element's length into ecx. 1365 // Get the element's length into ecx.
Jakob Kummerow 2012/02/08 16:24:55 s/element's/elements'/
1366 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); 1366 __ mov(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
1367 1367
1368 // Check if we could survive without allocation. 1368 // Check if we could survive without allocation.
1369 __ cmp(eax, ecx); 1369 __ cmp(eax, ecx);
1370 __ j(greater, &attempt_to_grow_elements); 1370 __ j(greater, &attempt_to_grow_elements);
1371 1371
1372 // Check if value is a smi. 1372 // Check if value is a smi.
1373 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1373 __ mov(ecx, Operand(esp, argc * kPointerSize));
1374 __ JumpIfNotSmi(ecx, &with_write_barrier); 1374 __ JumpIfNotSmi(ecx, &with_write_barrier);
1375 1375
1376 // Save new length. 1376 // Save new length.
1377 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1377 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1378 1378
1379 // Push the element. 1379 // Push the element.
Jakob Kummerow 2012/02/08 16:24:55 Maybe "Store the value"? or "Push the new element"
1380 __ lea(edx, FieldOperand(ebx, 1380 __ mov(FieldOperand(edi,
1381 eax, times_half_pointer_size, 1381 eax, times_half_pointer_size,
1382 FixedArray::kHeaderSize - argc * kPointerSize)); 1382 FixedArray::kHeaderSize - argc * kPointerSize),
1383 __ mov(Operand(edx, 0), ecx); 1383 ecx);
1384 1384
1385 __ ret((argc + 1) * kPointerSize); 1385 __ ret((argc + 1) * kPointerSize);
1386 1386
1387 __ bind(&with_write_barrier); 1387 __ bind(&with_write_barrier);
1388 1388
1389 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 1389 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
1390 __ CheckFastObjectElements(edi, &call_builtin); 1390
1391 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1392 Label fast_object, not_fast_object;
1393 __ CheckFastObjectElements(ebx, &not_fast_object, Label::kNear);
1394 __ jmp(&fast_object);
1395 // In case of fast smi-only, convert to fast object, otherwise bail out.
1396 __ bind(&not_fast_object);
1397 __ CheckFastSmiOnlyElements(ebx, &call_builtin);
1398 // edi: elements array
1399 // edx: receiver
1400 // ebx: map
1401 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
1402 FAST_ELEMENTS,
1403 ebx,
1404 edi,
1405 &call_builtin);
1406 ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm());
1407 // Restore edi.
1408 __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
1409 __ bind(&fast_object);
1410 } else {
1411 __ CheckFastObjectElements(ebx, &call_builtin);
1412 }
1391 1413
1392 // Save new length. 1414 // Save new length.
1393 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1415 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1394 1416
1395 // Push the element. 1417 // Push the element.
1396 __ lea(edx, FieldOperand(ebx, 1418 __ lea(edx, FieldOperand(edi,
1397 eax, times_half_pointer_size, 1419 eax, times_half_pointer_size,
1398 FixedArray::kHeaderSize - argc * kPointerSize)); 1420 FixedArray::kHeaderSize - argc * kPointerSize));
1399 __ mov(Operand(edx, 0), ecx); 1421 __ mov(Operand(edx, 0), ecx);
1400 1422
1401 __ RecordWrite(ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, 1423 __ RecordWrite(edi, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1402 OMIT_SMI_CHECK); 1424 OMIT_SMI_CHECK);
1403 1425
1404 __ ret((argc + 1) * kPointerSize); 1426 __ ret((argc + 1) * kPointerSize);
1405 1427
1406 __ bind(&attempt_to_grow_elements); 1428 __ bind(&attempt_to_grow_elements);
1407 if (!FLAG_inline_new) { 1429 if (!FLAG_inline_new) {
1408 __ jmp(&call_builtin); 1430 __ jmp(&call_builtin);
1409 } 1431 }
1410 1432
1411 __ mov(edi, Operand(esp, argc * kPointerSize)); 1433 __ mov(ebx, Operand(esp, argc * kPointerSize));
1412 // Growing elements that are SMI-only requires special handling in case 1434 // Growing elements that are SMI-only requires special handling in case
1413 // the new element is non-Smi. For now, delegate to the builtin. 1435 // the new element is non-Smi. For now, delegate to the builtin.
1414 Label no_fast_elements_check; 1436 Label no_fast_elements_check;
1415 __ JumpIfSmi(edi, &no_fast_elements_check); 1437 __ JumpIfSmi(ebx, &no_fast_elements_check);
1416 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 1438 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1417 __ CheckFastObjectElements(ecx, &call_builtin, Label::kFar); 1439 __ CheckFastObjectElements(ecx, &call_builtin, Label::kFar);
1418 __ bind(&no_fast_elements_check); 1440 __ bind(&no_fast_elements_check);
1419 1441
1420 // We could be lucky and the elements array could be at the top of 1442 // We could be lucky and the elements array could be at the top of
1421 // new-space. In this case we can just grow it in place by moving the 1443 // new-space. In this case we can just grow it in place by moving the
1422 // allocation pointer up. 1444 // allocation pointer up.
1423 1445
1424 ExternalReference new_space_allocation_top = 1446 ExternalReference new_space_allocation_top =
1425 ExternalReference::new_space_allocation_top_address(isolate()); 1447 ExternalReference::new_space_allocation_top_address(isolate());
1426 ExternalReference new_space_allocation_limit = 1448 ExternalReference new_space_allocation_limit =
1427 ExternalReference::new_space_allocation_limit_address(isolate()); 1449 ExternalReference::new_space_allocation_limit_address(isolate());
1428 1450
1429 const int kAllocationDelta = 4; 1451 const int kAllocationDelta = 4;
1430 // Load top. 1452 // Load top.
1431 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); 1453 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
1432 1454
1433 // Check if it's the end of elements. 1455 // Check if it's the end of elements.
1434 __ lea(edx, FieldOperand(ebx, 1456 __ lea(edx, FieldOperand(edi,
1435 eax, times_half_pointer_size, 1457 eax, times_half_pointer_size,
1436 FixedArray::kHeaderSize - argc * kPointerSize)); 1458 FixedArray::kHeaderSize - argc * kPointerSize));
1437 __ cmp(edx, ecx); 1459 __ cmp(edx, ecx);
1438 __ j(not_equal, &call_builtin); 1460 __ j(not_equal, &call_builtin);
1439 __ add(ecx, Immediate(kAllocationDelta * kPointerSize)); 1461 __ add(ecx, Immediate(kAllocationDelta * kPointerSize));
1440 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit)); 1462 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
1441 __ j(above, &call_builtin); 1463 __ j(above, &call_builtin);
1442 1464
1443 // We fit and could grow elements. 1465 // We fit and could grow elements.
1444 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); 1466 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
1445 1467
1446 // Push the argument... 1468 // Push the argument...
1447 __ mov(Operand(edx, 0), edi); 1469 __ mov(Operand(edx, 0), ebx);
1448 // ... and fill the rest with holes. 1470 // ... and fill the rest with holes.
1449 for (int i = 1; i < kAllocationDelta; i++) { 1471 for (int i = 1; i < kAllocationDelta; i++) {
1450 __ mov(Operand(edx, i * kPointerSize), 1472 __ mov(Operand(edx, i * kPointerSize),
1451 Immediate(factory()->the_hole_value())); 1473 Immediate(factory()->the_hole_value()));
1452 } 1474 }
1453 1475
1454 // We know the elements array is in new space so we don't need the 1476 // We know the elements array is in new space so we don't need the
1455 // remembered set, but we just pushed a value onto it so we may have to 1477 // remembered set, but we just pushed a value onto it so we may have to
1456 // tell the incremental marker to rescan the object that we just grew. We 1478 // tell the incremental marker to rescan the object that we just grew. We
1457 // don't need to worry about the holes because they are in old space and 1479 // don't need to worry about the holes because they are in old space and
1458 // already marked black. 1480 // already marked black.
1459 __ RecordWrite(ebx, edx, edi, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1481 __ RecordWrite(edi, edx, ebx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1460 1482
1461 // Restore receiver to edx as finish sequence assumes it's here. 1483 // Restore receiver to edx as finish sequence assumes it's here.
1462 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1484 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1463 1485
1464 // Increment element's and array's sizes. 1486 // Increment element's and array's sizes.
1465 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), 1487 __ add(FieldOperand(edi, FixedArray::kLengthOffset),
1466 Immediate(Smi::FromInt(kAllocationDelta))); 1488 Immediate(Smi::FromInt(kAllocationDelta)));
1467 1489
1468 // NOTE: This only happen in new-space, where we don't 1490 // NOTE: This only happen in new-space, where we don't
1469 // care about the black-byte-count on pages. Otherwise we should 1491 // care about the black-byte-count on pages. Otherwise we should
1470 // update that too if the object is black. 1492 // update that too if the object is black.
1471 1493
1472 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1494 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1473 1495
1474 __ ret((argc + 1) * kPointerSize); 1496 __ ret((argc + 1) * kPointerSize);
1475 } 1497 }
(...skipping 2339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3815 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3837 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3816 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 3838 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3817 } 3839 }
3818 3840
3819 3841
3820 #undef __ 3842 #undef __
3821 3843
3822 } } // namespace v8::internal 3844 } } // namespace v8::internal
3823 3845
3824 #endif // V8_TARGET_ARCH_IA32 3846 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698