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

Side by Side Diff: src/x64/stub-cache-x64.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
« src/ia32/stub-cache-ia32.cc ('K') | « src/ia32/stub-cache-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1324 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1325 name, &miss); 1325 name, &miss);
1326 1326
1327 if (argc == 0) { 1327 if (argc == 0) {
1328 // Noop, return the length. 1328 // Noop, return the length.
1329 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1329 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
1330 __ ret((argc + 1) * kPointerSize); 1330 __ ret((argc + 1) * kPointerSize);
1331 } else { 1331 } else {
1332 Label call_builtin; 1332 Label call_builtin;
1333 1333
1334 // Get the elements array of the object.
1335 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
1336
1337 // Check that the elements are in fast mode and writable.
1338 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
1339 factory()->fixed_array_map());
1340 __ j(not_equal, &call_builtin);
1341
1342 if (argc == 1) { // Otherwise fall through to call builtin. 1334 if (argc == 1) { // Otherwise fall through to call builtin.
1343 Label attempt_to_grow_elements, with_write_barrier; 1335 Label attempt_to_grow_elements, with_write_barrier;
1344 1336
1337 // Get the elements array of the object.
1338 __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset));
1339
1340 // Check that the elements are in fast mode and writable.
1341 __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset),
1342 factory()->fixed_array_map());
1343 __ j(not_equal, &call_builtin);
1344
1345 // Get the array's length into rax and calculate new length. 1345 // Get the array's length into rax and calculate new length.
1346 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1346 __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
1347 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 1347 STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue);
1348 __ addl(rax, Immediate(argc)); 1348 __ addl(rax, Immediate(argc));
1349 1349
1350 // Get the element's length into rcx. 1350 // Get the element's length into rcx.
1351 __ SmiToInteger32(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); 1351 __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
1352 1352
1353 // Check if we could survive without allocation. 1353 // Check if we could survive without allocation.
1354 __ cmpl(rax, rcx); 1354 __ cmpl(rax, rcx);
1355 __ j(greater, &attempt_to_grow_elements); 1355 __ j(greater, &attempt_to_grow_elements);
1356 1356
1357 // Check if value is a smi. 1357 // Check if value is a smi.
1358 __ movq(rcx, Operand(rsp, argc * kPointerSize)); 1358 __ movq(rcx, Operand(rsp, argc * kPointerSize));
1359 __ JumpIfNotSmi(rcx, &with_write_barrier); 1359 __ JumpIfNotSmi(rcx, &with_write_barrier);
1360 1360
1361 // Save new length. 1361 // Save new length.
1362 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1362 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1363 1363
1364 // Push the element. 1364 // Push the element.
1365 __ lea(rdx, FieldOperand(rbx, 1365 __ movq(FieldOperand(rdi,
1366 rax, times_pointer_size, 1366 rax, times_pointer_size,
Jakob Kummerow 2012/02/08 16:24:55 nit: I'd align this under "rdi".
1367 FixedArray::kHeaderSize - argc * kPointerSize)); 1367 FixedArray::kHeaderSize - argc * kPointerSize),
1368 __ movq(Operand(rdx, 0), rcx); 1368 rcx);
1369 1369
1370 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1370 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1371 __ ret((argc + 1) * kPointerSize); 1371 __ ret((argc + 1) * kPointerSize);
1372 1372
1373 __ bind(&with_write_barrier); 1373 __ bind(&with_write_barrier);
1374 1374
1375 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); 1375 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
1376 __ CheckFastObjectElements(rdi, &call_builtin); 1376
1377 if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) {
1378 Label fast_object, not_fast_object;
1379 __ CheckFastObjectElements(rbx, &not_fast_object, Label::kNear);
1380 __ jmp(&fast_object);
1381 // In case of fast smi-only, convert to fast object, otherwise bail out.
1382 __ bind(&not_fast_object);
1383 __ CheckFastSmiOnlyElements(rbx, &call_builtin);
1384 // rdx: receiver
1385 // rbx: map
1386 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
1387 FAST_ELEMENTS,
1388 rbx,
1389 r10,
1390 &call_builtin);
1391 ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm());
1392 __ bind(&fast_object);
1393 } else {
1394 __ CheckFastObjectElements(rbx, &call_builtin);
1395 }
1396
1397 __ CheckFastObjectElements(rbx, &call_builtin);
1377 1398
1378 // Save new length. 1399 // Save new length.
1379 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1400 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1380 1401
1381 // Push the element. 1402 // Push the element.
1382 __ lea(rdx, FieldOperand(rbx, 1403 __ lea(rdx, FieldOperand(rdi,
1383 rax, times_pointer_size, 1404 rax, times_pointer_size,
1384 FixedArray::kHeaderSize - argc * kPointerSize)); 1405 FixedArray::kHeaderSize - argc * kPointerSize));
1385 __ movq(Operand(rdx, 0), rcx); 1406 __ movq(Operand(rdx, 0), rcx);
1386 1407
1387 __ RecordWrite(rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, 1408 __ RecordWrite(rdi, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1388 OMIT_SMI_CHECK); 1409 OMIT_SMI_CHECK);
1389 1410
1390 __ Integer32ToSmi(rax, rax); // Return new length as smi. 1411 __ Integer32ToSmi(rax, rax); // Return new length as smi.
1391 __ ret((argc + 1) * kPointerSize); 1412 __ ret((argc + 1) * kPointerSize);
1392 1413
1393 __ bind(&attempt_to_grow_elements); 1414 __ bind(&attempt_to_grow_elements);
1394 if (!FLAG_inline_new) { 1415 if (!FLAG_inline_new) {
1395 __ jmp(&call_builtin); 1416 __ jmp(&call_builtin);
1396 } 1417 }
1397 1418
1398 __ movq(rdi, Operand(rsp, argc * kPointerSize)); 1419 __ movq(rbx, Operand(rsp, argc * kPointerSize));
1399 // Growing elements that are SMI-only requires special handling in case 1420 // Growing elements that are SMI-only requires special handling in case
1400 // the new element is non-Smi. For now, delegate to the builtin. 1421 // the new element is non-Smi. For now, delegate to the builtin.
1401 Label no_fast_elements_check; 1422 Label no_fast_elements_check;
1402 __ JumpIfSmi(rdi, &no_fast_elements_check); 1423 __ JumpIfSmi(rbx, &no_fast_elements_check);
1403 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 1424 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
1404 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar); 1425 __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar);
1405 __ bind(&no_fast_elements_check); 1426 __ bind(&no_fast_elements_check);
1406 1427
1407 ExternalReference new_space_allocation_top = 1428 ExternalReference new_space_allocation_top =
1408 ExternalReference::new_space_allocation_top_address(isolate()); 1429 ExternalReference::new_space_allocation_top_address(isolate());
1409 ExternalReference new_space_allocation_limit = 1430 ExternalReference new_space_allocation_limit =
1410 ExternalReference::new_space_allocation_limit_address(isolate()); 1431 ExternalReference::new_space_allocation_limit_address(isolate());
1411 1432
1412 const int kAllocationDelta = 4; 1433 const int kAllocationDelta = 4;
1413 // Load top. 1434 // Load top.
1414 __ Load(rcx, new_space_allocation_top); 1435 __ Load(rcx, new_space_allocation_top);
1415 1436
1416 // Check if it's the end of elements. 1437 // Check if it's the end of elements.
1417 __ lea(rdx, FieldOperand(rbx, 1438 __ lea(rdx, FieldOperand(rdi,
1418 rax, times_pointer_size, 1439 rax, times_pointer_size,
1419 FixedArray::kHeaderSize - argc * kPointerSize)); 1440 FixedArray::kHeaderSize - argc * kPointerSize));
1420 __ cmpq(rdx, rcx); 1441 __ cmpq(rdx, rcx);
1421 __ j(not_equal, &call_builtin); 1442 __ j(not_equal, &call_builtin);
1422 __ addq(rcx, Immediate(kAllocationDelta * kPointerSize)); 1443 __ addq(rcx, Immediate(kAllocationDelta * kPointerSize));
1423 Operand limit_operand = 1444 Operand limit_operand =
1424 masm()->ExternalOperand(new_space_allocation_limit); 1445 masm()->ExternalOperand(new_space_allocation_limit);
1425 __ cmpq(rcx, limit_operand); 1446 __ cmpq(rcx, limit_operand);
1426 __ j(above, &call_builtin); 1447 __ j(above, &call_builtin);
1427 1448
1428 // We fit and could grow elements. 1449 // We fit and could grow elements.
1429 __ Store(new_space_allocation_top, rcx); 1450 __ Store(new_space_allocation_top, rcx);
1430 1451
1431 // Push the argument... 1452 // Push the argument...
1432 __ movq(Operand(rdx, 0), rdi); 1453 __ movq(Operand(rdx, 0), rbx);
1433 // ... and fill the rest with holes. 1454 // ... and fill the rest with holes.
1434 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 1455 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
1435 for (int i = 1; i < kAllocationDelta; i++) { 1456 for (int i = 1; i < kAllocationDelta; i++) {
1436 __ movq(Operand(rdx, i * kPointerSize), kScratchRegister); 1457 __ movq(Operand(rdx, i * kPointerSize), kScratchRegister);
1437 } 1458 }
1438 1459
1439 // We know the elements array is in new space so we don't need the 1460 // We know the elements array is in new space so we don't need the
1440 // remembered set, but we just pushed a value onto it so we may have to 1461 // remembered set, but we just pushed a value onto it so we may have to
1441 // tell the incremental marker to rescan the object that we just grew. We 1462 // tell the incremental marker to rescan the object that we just grew. We
1442 // don't need to worry about the holes because they are in old space and 1463 // don't need to worry about the holes because they are in old space and
1443 // already marked black. 1464 // already marked black.
1444 __ RecordWrite(rbx, rdx, rdi, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1465 __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
1445 1466
1446 // Restore receiver to rdx as finish sequence assumes it's here. 1467 // Restore receiver to rdx as finish sequence assumes it's here.
1447 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1468 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1448 1469
1449 // Increment element's and array's sizes. 1470 // Increment element's and array's sizes.
1450 __ SmiAddConstant(FieldOperand(rbx, FixedArray::kLengthOffset), 1471 __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
1451 Smi::FromInt(kAllocationDelta)); 1472 Smi::FromInt(kAllocationDelta));
1452 1473
1453 // Make new length a smi before returning it. 1474 // Make new length a smi before returning it.
1454 __ Integer32ToSmi(rax, rax); 1475 __ Integer32ToSmi(rax, rax);
1455 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1476 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax);
1456 1477
1457 __ ret((argc + 1) * kPointerSize); 1478 __ ret((argc + 1) * kPointerSize);
1458 } 1479 }
1459 1480
1460 __ bind(&call_builtin); 1481 __ bind(&call_builtin);
(...skipping 2125 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3607 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3587 __ jmp(ic_miss, RelocInfo::CODE_TARGET); 3608 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3588 } 3609 }
3589 3610
3590 3611
3591 #undef __ 3612 #undef __
3592 3613
3593 } } // namespace v8::internal 3614 } } // namespace v8::internal
3594 3615
3595 #endif // V8_TARGET_ARCH_X64 3616 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/ia32/stub-cache-ia32.cc ('K') | « src/ia32/stub-cache-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698