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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 7497063: Simplify and optimize ToBoolean handling. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 4 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1403 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1404 1404
1405 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 1405 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1406 // Avoid deopts in the case where we've never executed this path before. 1406 // Avoid deopts in the case where we've never executed this path before.
1407 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 1407 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1408 1408
1409 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 1409 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1410 // undefined -> false. 1410 // undefined -> false.
1411 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 1411 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1412 __ j(equal, false_label); 1412 __ j(equal, false_label);
1413 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1414 // We've seen undefined for the first time -> deopt.
1415 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1416 DeoptimizeIf(equal, instr->environment());
1417 } 1413 }
1418
1419 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 1414 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1420 // true -> true. 1415 // true -> true.
1421 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1416 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1422 __ j(equal, true_label); 1417 __ j(equal, true_label);
1423 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1424 // We've seen a boolean for the first time -> deopt.
1425 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1426 DeoptimizeIf(equal, instr->environment());
1427 }
1428
1429 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1430 // false -> false. 1418 // false -> false.
1431 __ CompareRoot(reg, Heap::kFalseValueRootIndex); 1419 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1432 __ j(equal, false_label); 1420 __ j(equal, false_label);
1433 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1434 // We've seen a boolean for the first time -> deopt.
1435 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1436 DeoptimizeIf(equal, instr->environment());
1437 } 1421 }
1438
1439 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 1422 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1440 // 'null' -> false. 1423 // 'null' -> false.
1441 __ CompareRoot(reg, Heap::kNullValueRootIndex); 1424 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1442 __ j(equal, false_label); 1425 __ j(equal, false_label);
1443 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1444 // We've seen null for the first time -> deopt.
1445 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1446 DeoptimizeIf(equal, instr->environment());
1447 } 1426 }
1448 1427
1449 if (expected.Contains(ToBooleanStub::SMI)) { 1428 if (expected.Contains(ToBooleanStub::SMI)) {
1450 // Smis: 0 -> false, all other -> true. 1429 // Smis: 0 -> false, all other -> true.
1451 __ Cmp(reg, Smi::FromInt(0)); 1430 __ Cmp(reg, Smi::FromInt(0));
1452 __ j(equal, false_label); 1431 __ j(equal, false_label);
1453 __ JumpIfSmi(reg, true_label); 1432 __ JumpIfSmi(reg, true_label);
1454 } else if (expected.NeedsMap()) { 1433 } else if (expected.NeedsMap()) {
1455 // If we need a map later and have a Smi -> deopt. 1434 // If we need a map later and have a Smi -> deopt.
1456 __ testb(reg, Immediate(kSmiTagMask)); 1435 __ testb(reg, Immediate(kSmiTagMask));
1457 DeoptimizeIf(zero, instr->environment()); 1436 DeoptimizeIf(zero, instr->environment());
1458 } 1437 }
1459 1438
1460 const Register map = kScratchRegister; 1439 const Register map = kScratchRegister;
1461 if (expected.NeedsMap()) { 1440 if (expected.NeedsMap()) {
1462 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset)); 1441 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset));
1463 // Everything with a map could be undetectable, so check this now. 1442
1464 __ testb(FieldOperand(map, Map::kBitFieldOffset), 1443 if (expected.CanBeUndetectable()) {
1465 Immediate(1 << Map::kIsUndetectable)); 1444 // Undetectable -> false.
1466 // Undetectable -> false. 1445 __ testb(FieldOperand(map, Map::kBitFieldOffset),
1467 __ j(not_zero, false_label); 1446 Immediate(1 << Map::kIsUndetectable));
1447 __ j(not_zero, false_label);
1448 }
1468 } 1449 }
1469 1450
1470 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 1451 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1471 // spec object -> true. 1452 // spec object -> true.
1472 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 1453 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1473 __ j(above_equal, true_label); 1454 __ j(above_equal, true_label);
1474 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1475 // We've seen a spec object for the first time -> deopt.
1476 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1477 DeoptimizeIf(above_equal, instr->environment());
1478 } 1455 }
1479 1456
1480 if (expected.Contains(ToBooleanStub::STRING)) { 1457 if (expected.Contains(ToBooleanStub::STRING)) {
1481 // String value -> false iff empty. 1458 // String value -> false iff empty.
1482 Label not_string; 1459 Label not_string;
1483 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 1460 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1484 __ j(above_equal, &not_string, Label::kNear); 1461 __ j(above_equal, &not_string, Label::kNear);
1485 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 1462 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0));
1486 __ j(not_zero, true_label); 1463 __ j(not_zero, true_label);
1487 __ jmp(false_label); 1464 __ jmp(false_label);
1488 __ bind(&not_string); 1465 __ bind(&not_string);
1489 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1490 // We've seen a string for the first time -> deopt
1491 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1492 DeoptimizeIf(below, instr->environment());
1493 } 1466 }
1494 1467
1495 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 1468 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1496 // heap number -> false iff +0, -0, or NaN. 1469 // heap number -> false iff +0, -0, or NaN.
1497 Label not_heap_number; 1470 Label not_heap_number;
1498 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1471 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1499 __ j(not_equal, &not_heap_number, Label::kNear); 1472 __ j(not_equal, &not_heap_number, Label::kNear);
1500 __ xorps(xmm0, xmm0); 1473 __ xorps(xmm0, xmm0);
1501 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 1474 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
1502 __ j(zero, false_label); 1475 __ j(zero, false_label);
1503 __ jmp(true_label); 1476 __ jmp(true_label);
1504 __ bind(&not_heap_number); 1477 __ bind(&not_heap_number);
1505 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1506 // We've seen a heap number for the first time -> deopt.
1507 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1508 DeoptimizeIf(equal, instr->environment());
1509 } 1478 }
1510 1479
1511 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { 1480 // We've seen something for the first time -> deopt.
1512 // internal objects -> true 1481 DeoptimizeIf(no_condition, instr->environment());
1513 __ jmp(true_label);
1514 } else {
1515 // We've seen something for the first time -> deopt.
1516 DeoptimizeIf(no_condition, instr->environment());
1517 }
1518 } 1482 }
1519 } 1483 }
1520 } 1484 }
1521 1485
1522 1486
1523 void LCodeGen::EmitGoto(int block) { 1487 void LCodeGen::EmitGoto(int block) {
1524 block = chunk_->LookupDestination(block); 1488 block = chunk_->LookupDestination(block);
1525 int next_block = GetNextEmittedBlock(current_block_); 1489 int next_block = GetNextEmittedBlock(current_block_);
1526 if (block != next_block) { 1490 if (block != next_block) {
1527 __ jmp(chunk_->GetAssemblyLabel(block)); 1491 __ jmp(chunk_->GetAssemblyLabel(block));
(...skipping 2656 matching lines...) Expand 10 before | Expand all | Expand 10 after
4184 RegisterEnvironmentForDeoptimization(environment); 4148 RegisterEnvironmentForDeoptimization(environment);
4185 ASSERT(osr_pc_offset_ == -1); 4149 ASSERT(osr_pc_offset_ == -1);
4186 osr_pc_offset_ = masm()->pc_offset(); 4150 osr_pc_offset_ = masm()->pc_offset();
4187 } 4151 }
4188 4152
4189 #undef __ 4153 #undef __
4190 4154
4191 } } // namespace v8::internal 4155 } } // namespace v8::internal
4192 4156
4193 #endif // V8_TARGET_ARCH_X64 4157 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/apinatives.js ('K') | « src/x64/code-stubs-x64.cc ('k') | src/x64/lithium-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698