| OLD | NEW |
| 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 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 } | 581 } |
| 582 | 582 |
| 583 | 583 |
| 584 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { | 584 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { |
| 585 int length = deoptimizations_.length(); | 585 int length = deoptimizations_.length(); |
| 586 if (length == 0) return; | 586 if (length == 0) return; |
| 587 ASSERT(FLAG_deopt); | 587 ASSERT(FLAG_deopt); |
| 588 Handle<DeoptimizationInputData> data = | 588 Handle<DeoptimizationInputData> data = |
| 589 FACTORY->NewDeoptimizationInputData(length, TENURED); | 589 factory()->NewDeoptimizationInputData(length, TENURED); |
| 590 | 590 |
| 591 Handle<ByteArray> translations = translations_.CreateByteArray(); | 591 Handle<ByteArray> translations = translations_.CreateByteArray(); |
| 592 data->SetTranslationByteArray(*translations); | 592 data->SetTranslationByteArray(*translations); |
| 593 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 593 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
| 594 | 594 |
| 595 Handle<FixedArray> literals = | 595 Handle<FixedArray> literals = |
| 596 FACTORY->NewFixedArray(deoptimization_literals_.length(), TENURED); | 596 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
| 597 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 597 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 598 literals->set(i, *deoptimization_literals_[i]); | 598 literals->set(i, *deoptimization_literals_[i]); |
| 599 } | 599 } |
| 600 data->SetLiteralArray(*literals); | 600 data->SetLiteralArray(*literals); |
| 601 | 601 |
| 602 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); | 602 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); |
| 603 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 603 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
| 604 | 604 |
| 605 // Populate the deoptimization entries. | 605 // Populate the deoptimization entries. |
| 606 for (int i = 0; i < length; i++) { | 606 for (int i = 0; i < length; i++) { |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 double v = instr->value(); | 1046 double v = instr->value(); |
| 1047 // Use xor to produce +0.0 in a fast and compact way, but avoid to | 1047 // Use xor to produce +0.0 in a fast and compact way, but avoid to |
| 1048 // do so if the constant is -0.0. | 1048 // do so if the constant is -0.0. |
| 1049 if (BitCast<uint64_t, double>(v) == 0) { | 1049 if (BitCast<uint64_t, double>(v) == 0) { |
| 1050 __ xorpd(res, res); | 1050 __ xorpd(res, res); |
| 1051 } else { | 1051 } else { |
| 1052 Register temp = ToRegister(instr->TempAt(0)); | 1052 Register temp = ToRegister(instr->TempAt(0)); |
| 1053 uint64_t int_val = BitCast<uint64_t, double>(v); | 1053 uint64_t int_val = BitCast<uint64_t, double>(v); |
| 1054 int32_t lower = static_cast<int32_t>(int_val); | 1054 int32_t lower = static_cast<int32_t>(int_val); |
| 1055 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 1055 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
| 1056 if (Isolate::Current()->cpu_features()->IsSupported(SSE4_1)) { | 1056 if (isolate()->cpu_features()->IsSupported(SSE4_1)) { |
| 1057 CpuFeatures::Scope scope(SSE4_1); | 1057 CpuFeatures::Scope scope(SSE4_1); |
| 1058 if (lower != 0) { | 1058 if (lower != 0) { |
| 1059 __ Set(temp, Immediate(lower)); | 1059 __ Set(temp, Immediate(lower)); |
| 1060 __ movd(res, Operand(temp)); | 1060 __ movd(res, Operand(temp)); |
| 1061 __ Set(temp, Immediate(upper)); | 1061 __ Set(temp, Immediate(upper)); |
| 1062 __ pinsrd(res, Operand(temp), 1); | 1062 __ pinsrd(res, Operand(temp), 1); |
| 1063 } else { | 1063 } else { |
| 1064 __ xorpd(res, res); | 1064 __ xorpd(res, res); |
| 1065 __ Set(temp, Immediate(upper)); | 1065 __ Set(temp, Immediate(upper)); |
| 1066 __ pinsrd(res, Operand(temp), 1); | 1066 __ pinsrd(res, Operand(temp), 1); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 EmitBranch(true_block, false_block, not_zero); | 1249 EmitBranch(true_block, false_block, not_zero); |
| 1250 } else if (r.IsDouble()) { | 1250 } else if (r.IsDouble()) { |
| 1251 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); | 1251 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); |
| 1252 __ xorpd(xmm0, xmm0); | 1252 __ xorpd(xmm0, xmm0); |
| 1253 __ ucomisd(reg, xmm0); | 1253 __ ucomisd(reg, xmm0); |
| 1254 EmitBranch(true_block, false_block, not_equal); | 1254 EmitBranch(true_block, false_block, not_equal); |
| 1255 } else { | 1255 } else { |
| 1256 ASSERT(r.IsTagged()); | 1256 ASSERT(r.IsTagged()); |
| 1257 Register reg = ToRegister(instr->InputAt(0)); | 1257 Register reg = ToRegister(instr->InputAt(0)); |
| 1258 if (instr->hydrogen()->type().IsBoolean()) { | 1258 if (instr->hydrogen()->type().IsBoolean()) { |
| 1259 __ cmp(reg, FACTORY->true_value()); | 1259 __ cmp(reg, factory()->true_value()); |
| 1260 EmitBranch(true_block, false_block, equal); | 1260 EmitBranch(true_block, false_block, equal); |
| 1261 } else { | 1261 } else { |
| 1262 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1262 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1263 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1263 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1264 | 1264 |
| 1265 __ cmp(reg, FACTORY->undefined_value()); | 1265 __ cmp(reg, factory()->undefined_value()); |
| 1266 __ j(equal, false_label); | 1266 __ j(equal, false_label); |
| 1267 __ cmp(reg, FACTORY->true_value()); | 1267 __ cmp(reg, factory()->true_value()); |
| 1268 __ j(equal, true_label); | 1268 __ j(equal, true_label); |
| 1269 __ cmp(reg, FACTORY->false_value()); | 1269 __ cmp(reg, factory()->false_value()); |
| 1270 __ j(equal, false_label); | 1270 __ j(equal, false_label); |
| 1271 __ test(reg, Operand(reg)); | 1271 __ test(reg, Operand(reg)); |
| 1272 __ j(equal, false_label); | 1272 __ j(equal, false_label); |
| 1273 __ test(reg, Immediate(kSmiTagMask)); | 1273 __ test(reg, Immediate(kSmiTagMask)); |
| 1274 __ j(zero, true_label); | 1274 __ j(zero, true_label); |
| 1275 | 1275 |
| 1276 // Test for double values. Zero is false. | 1276 // Test for double values. Zero is false. |
| 1277 NearLabel call_stub; | 1277 NearLabel call_stub; |
| 1278 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1278 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1279 FACTORY->heap_number_map()); | 1279 factory()->heap_number_map()); |
| 1280 __ j(not_equal, &call_stub); | 1280 __ j(not_equal, &call_stub); |
| 1281 __ fldz(); | 1281 __ fldz(); |
| 1282 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 1282 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 1283 __ FCmp(); | 1283 __ FCmp(); |
| 1284 __ j(zero, false_label); | 1284 __ j(zero, false_label); |
| 1285 __ jmp(true_label); | 1285 __ jmp(true_label); |
| 1286 | 1286 |
| 1287 // The conversion stub doesn't cause garbage collections so it's | 1287 // The conversion stub doesn't cause garbage collections so it's |
| 1288 // safe to not record a safepoint after the call. | 1288 // safe to not record a safepoint after the call. |
| 1289 __ bind(&call_stub); | 1289 __ bind(&call_stub); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 // Don't base result on EFLAGS when a NaN is involved. Instead | 1392 // Don't base result on EFLAGS when a NaN is involved. Instead |
| 1393 // jump to the unordered case, which produces a false value. | 1393 // jump to the unordered case, which produces a false value. |
| 1394 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 1394 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 1395 __ j(parity_even, &unordered, not_taken); | 1395 __ j(parity_even, &unordered, not_taken); |
| 1396 } else { | 1396 } else { |
| 1397 EmitCmpI(left, right); | 1397 EmitCmpI(left, right); |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 NearLabel done; | 1400 NearLabel done; |
| 1401 Condition cc = TokenToCondition(instr->op(), instr->is_double()); | 1401 Condition cc = TokenToCondition(instr->op(), instr->is_double()); |
| 1402 __ mov(ToRegister(result), FACTORY->true_value()); | 1402 __ mov(ToRegister(result), factory()->true_value()); |
| 1403 __ j(cc, &done); | 1403 __ j(cc, &done); |
| 1404 | 1404 |
| 1405 __ bind(&unordered); | 1405 __ bind(&unordered); |
| 1406 __ mov(ToRegister(result), FACTORY->false_value()); | 1406 __ mov(ToRegister(result), factory()->false_value()); |
| 1407 __ bind(&done); | 1407 __ bind(&done); |
| 1408 } | 1408 } |
| 1409 | 1409 |
| 1410 | 1410 |
| 1411 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 1411 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { |
| 1412 LOperand* left = instr->InputAt(0); | 1412 LOperand* left = instr->InputAt(0); |
| 1413 LOperand* right = instr->InputAt(1); | 1413 LOperand* right = instr->InputAt(1); |
| 1414 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1414 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1415 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1415 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1416 | 1416 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1427 EmitBranch(true_block, false_block, cc); | 1427 EmitBranch(true_block, false_block, cc); |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 | 1430 |
| 1431 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { | 1431 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { |
| 1432 Register left = ToRegister(instr->InputAt(0)); | 1432 Register left = ToRegister(instr->InputAt(0)); |
| 1433 Register right = ToRegister(instr->InputAt(1)); | 1433 Register right = ToRegister(instr->InputAt(1)); |
| 1434 Register result = ToRegister(instr->result()); | 1434 Register result = ToRegister(instr->result()); |
| 1435 | 1435 |
| 1436 __ cmp(left, Operand(right)); | 1436 __ cmp(left, Operand(right)); |
| 1437 __ mov(result, FACTORY->true_value()); | 1437 __ mov(result, factory()->true_value()); |
| 1438 NearLabel done; | 1438 NearLabel done; |
| 1439 __ j(equal, &done); | 1439 __ j(equal, &done); |
| 1440 __ mov(result, FACTORY->false_value()); | 1440 __ mov(result, factory()->false_value()); |
| 1441 __ bind(&done); | 1441 __ bind(&done); |
| 1442 } | 1442 } |
| 1443 | 1443 |
| 1444 | 1444 |
| 1445 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { | 1445 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { |
| 1446 Register left = ToRegister(instr->InputAt(0)); | 1446 Register left = ToRegister(instr->InputAt(0)); |
| 1447 Register right = ToRegister(instr->InputAt(1)); | 1447 Register right = ToRegister(instr->InputAt(1)); |
| 1448 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1448 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1449 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1449 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1450 | 1450 |
| 1451 __ cmp(left, Operand(right)); | 1451 __ cmp(left, Operand(right)); |
| 1452 EmitBranch(true_block, false_block, equal); | 1452 EmitBranch(true_block, false_block, equal); |
| 1453 } | 1453 } |
| 1454 | 1454 |
| 1455 | 1455 |
| 1456 void LCodeGen::DoIsNull(LIsNull* instr) { | 1456 void LCodeGen::DoIsNull(LIsNull* instr) { |
| 1457 Register reg = ToRegister(instr->InputAt(0)); | 1457 Register reg = ToRegister(instr->InputAt(0)); |
| 1458 Register result = ToRegister(instr->result()); | 1458 Register result = ToRegister(instr->result()); |
| 1459 | 1459 |
| 1460 // TODO(fsc): If the expression is known to be a smi, then it's | 1460 // TODO(fsc): If the expression is known to be a smi, then it's |
| 1461 // definitely not null. Materialize false. | 1461 // definitely not null. Materialize false. |
| 1462 | 1462 |
| 1463 __ cmp(reg, FACTORY->null_value()); | 1463 __ cmp(reg, factory()->null_value()); |
| 1464 if (instr->is_strict()) { | 1464 if (instr->is_strict()) { |
| 1465 __ mov(result, FACTORY->true_value()); | 1465 __ mov(result, factory()->true_value()); |
| 1466 NearLabel done; | 1466 NearLabel done; |
| 1467 __ j(equal, &done); | 1467 __ j(equal, &done); |
| 1468 __ mov(result, FACTORY->false_value()); | 1468 __ mov(result, factory()->false_value()); |
| 1469 __ bind(&done); | 1469 __ bind(&done); |
| 1470 } else { | 1470 } else { |
| 1471 NearLabel true_value, false_value, done; | 1471 NearLabel true_value, false_value, done; |
| 1472 __ j(equal, &true_value); | 1472 __ j(equal, &true_value); |
| 1473 __ cmp(reg, FACTORY->undefined_value()); | 1473 __ cmp(reg, factory()->undefined_value()); |
| 1474 __ j(equal, &true_value); | 1474 __ j(equal, &true_value); |
| 1475 __ test(reg, Immediate(kSmiTagMask)); | 1475 __ test(reg, Immediate(kSmiTagMask)); |
| 1476 __ j(zero, &false_value); | 1476 __ j(zero, &false_value); |
| 1477 // Check for undetectable objects by looking in the bit field in | 1477 // Check for undetectable objects by looking in the bit field in |
| 1478 // the map. The object has already been smi checked. | 1478 // the map. The object has already been smi checked. |
| 1479 Register scratch = result; | 1479 Register scratch = result; |
| 1480 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 1480 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1481 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); | 1481 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); |
| 1482 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); | 1482 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); |
| 1483 __ j(not_zero, &true_value); | 1483 __ j(not_zero, &true_value); |
| 1484 __ bind(&false_value); | 1484 __ bind(&false_value); |
| 1485 __ mov(result, FACTORY->false_value()); | 1485 __ mov(result, factory()->false_value()); |
| 1486 __ jmp(&done); | 1486 __ jmp(&done); |
| 1487 __ bind(&true_value); | 1487 __ bind(&true_value); |
| 1488 __ mov(result, FACTORY->true_value()); | 1488 __ mov(result, factory()->true_value()); |
| 1489 __ bind(&done); | 1489 __ bind(&done); |
| 1490 } | 1490 } |
| 1491 } | 1491 } |
| 1492 | 1492 |
| 1493 | 1493 |
| 1494 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { | 1494 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { |
| 1495 Register reg = ToRegister(instr->InputAt(0)); | 1495 Register reg = ToRegister(instr->InputAt(0)); |
| 1496 | 1496 |
| 1497 // TODO(fsc): If the expression is known to be a smi, then it's | 1497 // TODO(fsc): If the expression is known to be a smi, then it's |
| 1498 // definitely not null. Jump to the false block. | 1498 // definitely not null. Jump to the false block. |
| 1499 | 1499 |
| 1500 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1500 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1501 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1501 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1502 | 1502 |
| 1503 __ cmp(reg, FACTORY->null_value()); | 1503 __ cmp(reg, factory()->null_value()); |
| 1504 if (instr->is_strict()) { | 1504 if (instr->is_strict()) { |
| 1505 EmitBranch(true_block, false_block, equal); | 1505 EmitBranch(true_block, false_block, equal); |
| 1506 } else { | 1506 } else { |
| 1507 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1507 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1508 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1508 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1509 __ j(equal, true_label); | 1509 __ j(equal, true_label); |
| 1510 __ cmp(reg, FACTORY->undefined_value()); | 1510 __ cmp(reg, factory()->undefined_value()); |
| 1511 __ j(equal, true_label); | 1511 __ j(equal, true_label); |
| 1512 __ test(reg, Immediate(kSmiTagMask)); | 1512 __ test(reg, Immediate(kSmiTagMask)); |
| 1513 __ j(zero, false_label); | 1513 __ j(zero, false_label); |
| 1514 // Check for undetectable objects by looking in the bit field in | 1514 // Check for undetectable objects by looking in the bit field in |
| 1515 // the map. The object has already been smi checked. | 1515 // the map. The object has already been smi checked. |
| 1516 Register scratch = ToRegister(instr->TempAt(0)); | 1516 Register scratch = ToRegister(instr->TempAt(0)); |
| 1517 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 1517 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1518 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); | 1518 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); |
| 1519 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); | 1519 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); |
| 1520 EmitBranch(true_block, false_block, not_zero); | 1520 EmitBranch(true_block, false_block, not_zero); |
| 1521 } | 1521 } |
| 1522 } | 1522 } |
| 1523 | 1523 |
| 1524 | 1524 |
| 1525 Condition LCodeGen::EmitIsObject(Register input, | 1525 Condition LCodeGen::EmitIsObject(Register input, |
| 1526 Register temp1, | 1526 Register temp1, |
| 1527 Register temp2, | 1527 Register temp2, |
| 1528 Label* is_not_object, | 1528 Label* is_not_object, |
| 1529 Label* is_object) { | 1529 Label* is_object) { |
| 1530 ASSERT(!input.is(temp1)); | 1530 ASSERT(!input.is(temp1)); |
| 1531 ASSERT(!input.is(temp2)); | 1531 ASSERT(!input.is(temp2)); |
| 1532 ASSERT(!temp1.is(temp2)); | 1532 ASSERT(!temp1.is(temp2)); |
| 1533 | 1533 |
| 1534 __ test(input, Immediate(kSmiTagMask)); | 1534 __ test(input, Immediate(kSmiTagMask)); |
| 1535 __ j(equal, is_not_object); | 1535 __ j(equal, is_not_object); |
| 1536 | 1536 |
| 1537 __ cmp(input, FACTORY->null_value()); | 1537 __ cmp(input, isolate()->factory()->null_value()); |
| 1538 __ j(equal, is_object); | 1538 __ j(equal, is_object); |
| 1539 | 1539 |
| 1540 __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset)); | 1540 __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset)); |
| 1541 // Undetectable objects behave like undefined. | 1541 // Undetectable objects behave like undefined. |
| 1542 __ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset)); | 1542 __ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset)); |
| 1543 __ test(temp2, Immediate(1 << Map::kIsUndetectable)); | 1543 __ test(temp2, Immediate(1 << Map::kIsUndetectable)); |
| 1544 __ j(not_zero, is_not_object); | 1544 __ j(not_zero, is_not_object); |
| 1545 | 1545 |
| 1546 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset)); | 1546 __ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset)); |
| 1547 __ cmp(temp2, FIRST_JS_OBJECT_TYPE); | 1547 __ cmp(temp2, FIRST_JS_OBJECT_TYPE); |
| 1548 __ j(below, is_not_object); | 1548 __ j(below, is_not_object); |
| 1549 __ cmp(temp2, LAST_JS_OBJECT_TYPE); | 1549 __ cmp(temp2, LAST_JS_OBJECT_TYPE); |
| 1550 return below_equal; | 1550 return below_equal; |
| 1551 } | 1551 } |
| 1552 | 1552 |
| 1553 | 1553 |
| 1554 void LCodeGen::DoIsObject(LIsObject* instr) { | 1554 void LCodeGen::DoIsObject(LIsObject* instr) { |
| 1555 Register reg = ToRegister(instr->InputAt(0)); | 1555 Register reg = ToRegister(instr->InputAt(0)); |
| 1556 Register result = ToRegister(instr->result()); | 1556 Register result = ToRegister(instr->result()); |
| 1557 Register temp = ToRegister(instr->TempAt(0)); | 1557 Register temp = ToRegister(instr->TempAt(0)); |
| 1558 Label is_false, is_true, done; | 1558 Label is_false, is_true, done; |
| 1559 | 1559 |
| 1560 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); | 1560 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); |
| 1561 __ j(true_cond, &is_true); | 1561 __ j(true_cond, &is_true); |
| 1562 | 1562 |
| 1563 __ bind(&is_false); | 1563 __ bind(&is_false); |
| 1564 __ mov(result, FACTORY->false_value()); | 1564 __ mov(result, factory()->false_value()); |
| 1565 __ jmp(&done); | 1565 __ jmp(&done); |
| 1566 | 1566 |
| 1567 __ bind(&is_true); | 1567 __ bind(&is_true); |
| 1568 __ mov(result, FACTORY->true_value()); | 1568 __ mov(result, factory()->true_value()); |
| 1569 | 1569 |
| 1570 __ bind(&done); | 1570 __ bind(&done); |
| 1571 } | 1571 } |
| 1572 | 1572 |
| 1573 | 1573 |
| 1574 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { | 1574 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { |
| 1575 Register reg = ToRegister(instr->InputAt(0)); | 1575 Register reg = ToRegister(instr->InputAt(0)); |
| 1576 Register temp = ToRegister(instr->TempAt(0)); | 1576 Register temp = ToRegister(instr->TempAt(0)); |
| 1577 Register temp2 = ToRegister(instr->TempAt(1)); | 1577 Register temp2 = ToRegister(instr->TempAt(1)); |
| 1578 | 1578 |
| 1579 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1579 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1580 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1580 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1581 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1581 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1582 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1582 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1583 | 1583 |
| 1584 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); | 1584 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); |
| 1585 | 1585 |
| 1586 EmitBranch(true_block, false_block, true_cond); | 1586 EmitBranch(true_block, false_block, true_cond); |
| 1587 } | 1587 } |
| 1588 | 1588 |
| 1589 | 1589 |
| 1590 void LCodeGen::DoIsSmi(LIsSmi* instr) { | 1590 void LCodeGen::DoIsSmi(LIsSmi* instr) { |
| 1591 Operand input = ToOperand(instr->InputAt(0)); | 1591 Operand input = ToOperand(instr->InputAt(0)); |
| 1592 Register result = ToRegister(instr->result()); | 1592 Register result = ToRegister(instr->result()); |
| 1593 | 1593 |
| 1594 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1594 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1595 __ test(input, Immediate(kSmiTagMask)); | 1595 __ test(input, Immediate(kSmiTagMask)); |
| 1596 __ mov(result, FACTORY->true_value()); | 1596 __ mov(result, factory()->true_value()); |
| 1597 NearLabel done; | 1597 NearLabel done; |
| 1598 __ j(zero, &done); | 1598 __ j(zero, &done); |
| 1599 __ mov(result, FACTORY->false_value()); | 1599 __ mov(result, factory()->false_value()); |
| 1600 __ bind(&done); | 1600 __ bind(&done); |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 | 1603 |
| 1604 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1604 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
| 1605 Operand input = ToOperand(instr->InputAt(0)); | 1605 Operand input = ToOperand(instr->InputAt(0)); |
| 1606 | 1606 |
| 1607 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1607 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1608 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1608 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1609 | 1609 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1635 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 1635 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { |
| 1636 Register input = ToRegister(instr->InputAt(0)); | 1636 Register input = ToRegister(instr->InputAt(0)); |
| 1637 Register result = ToRegister(instr->result()); | 1637 Register result = ToRegister(instr->result()); |
| 1638 | 1638 |
| 1639 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1639 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1640 __ test(input, Immediate(kSmiTagMask)); | 1640 __ test(input, Immediate(kSmiTagMask)); |
| 1641 NearLabel done, is_false; | 1641 NearLabel done, is_false; |
| 1642 __ j(zero, &is_false); | 1642 __ j(zero, &is_false); |
| 1643 __ CmpObjectType(input, TestType(instr->hydrogen()), result); | 1643 __ CmpObjectType(input, TestType(instr->hydrogen()), result); |
| 1644 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); | 1644 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); |
| 1645 __ mov(result, FACTORY->true_value()); | 1645 __ mov(result, factory()->true_value()); |
| 1646 __ jmp(&done); | 1646 __ jmp(&done); |
| 1647 __ bind(&is_false); | 1647 __ bind(&is_false); |
| 1648 __ mov(result, FACTORY->false_value()); | 1648 __ mov(result, factory()->false_value()); |
| 1649 __ bind(&done); | 1649 __ bind(&done); |
| 1650 } | 1650 } |
| 1651 | 1651 |
| 1652 | 1652 |
| 1653 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1653 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
| 1654 Register input = ToRegister(instr->InputAt(0)); | 1654 Register input = ToRegister(instr->InputAt(0)); |
| 1655 Register temp = ToRegister(instr->TempAt(0)); | 1655 Register temp = ToRegister(instr->TempAt(0)); |
| 1656 | 1656 |
| 1657 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1657 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1658 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1658 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1678 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); | 1678 __ mov(result, FieldOperand(input, String::kHashFieldOffset)); |
| 1679 __ IndexFromHash(result, result); | 1679 __ IndexFromHash(result, result); |
| 1680 } | 1680 } |
| 1681 | 1681 |
| 1682 | 1682 |
| 1683 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { | 1683 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { |
| 1684 Register input = ToRegister(instr->InputAt(0)); | 1684 Register input = ToRegister(instr->InputAt(0)); |
| 1685 Register result = ToRegister(instr->result()); | 1685 Register result = ToRegister(instr->result()); |
| 1686 | 1686 |
| 1687 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1687 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1688 __ mov(result, FACTORY->true_value()); | 1688 __ mov(result, factory()->true_value()); |
| 1689 __ test(FieldOperand(input, String::kHashFieldOffset), | 1689 __ test(FieldOperand(input, String::kHashFieldOffset), |
| 1690 Immediate(String::kContainsCachedArrayIndexMask)); | 1690 Immediate(String::kContainsCachedArrayIndexMask)); |
| 1691 NearLabel done; | 1691 NearLabel done; |
| 1692 __ j(zero, &done); | 1692 __ j(zero, &done); |
| 1693 __ mov(result, FACTORY->false_value()); | 1693 __ mov(result, factory()->false_value()); |
| 1694 __ bind(&done); | 1694 __ bind(&done); |
| 1695 } | 1695 } |
| 1696 | 1696 |
| 1697 | 1697 |
| 1698 void LCodeGen::DoHasCachedArrayIndexAndBranch( | 1698 void LCodeGen::DoHasCachedArrayIndexAndBranch( |
| 1699 LHasCachedArrayIndexAndBranch* instr) { | 1699 LHasCachedArrayIndexAndBranch* instr) { |
| 1700 Register input = ToRegister(instr->InputAt(0)); | 1700 Register input = ToRegister(instr->InputAt(0)); |
| 1701 | 1701 |
| 1702 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1702 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1703 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1703 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1772 Register temp = ToRegister(instr->TempAt(0)); | 1772 Register temp = ToRegister(instr->TempAt(0)); |
| 1773 Handle<String> class_name = instr->hydrogen()->class_name(); | 1773 Handle<String> class_name = instr->hydrogen()->class_name(); |
| 1774 NearLabel done; | 1774 NearLabel done; |
| 1775 Label is_true, is_false; | 1775 Label is_true, is_false; |
| 1776 | 1776 |
| 1777 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); | 1777 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); |
| 1778 | 1778 |
| 1779 __ j(not_equal, &is_false); | 1779 __ j(not_equal, &is_false); |
| 1780 | 1780 |
| 1781 __ bind(&is_true); | 1781 __ bind(&is_true); |
| 1782 __ mov(result, FACTORY->true_value()); | 1782 __ mov(result, factory()->true_value()); |
| 1783 __ jmp(&done); | 1783 __ jmp(&done); |
| 1784 | 1784 |
| 1785 __ bind(&is_false); | 1785 __ bind(&is_false); |
| 1786 __ mov(result, FACTORY->false_value()); | 1786 __ mov(result, factory()->false_value()); |
| 1787 __ bind(&done); | 1787 __ bind(&done); |
| 1788 } | 1788 } |
| 1789 | 1789 |
| 1790 | 1790 |
| 1791 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 1791 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { |
| 1792 Register input = ToRegister(instr->InputAt(0)); | 1792 Register input = ToRegister(instr->InputAt(0)); |
| 1793 Register temp = ToRegister(instr->TempAt(0)); | 1793 Register temp = ToRegister(instr->TempAt(0)); |
| 1794 Register temp2 = ToRegister(instr->TempAt(1)); | 1794 Register temp2 = ToRegister(instr->TempAt(1)); |
| 1795 if (input.is(temp)) { | 1795 if (input.is(temp)) { |
| 1796 // Swap. | 1796 // Swap. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1824 | 1824 |
| 1825 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 1825 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
| 1826 // Object and function are in fixed registers defined by the stub. | 1826 // Object and function are in fixed registers defined by the stub. |
| 1827 ASSERT(ToRegister(instr->context()).is(esi)); | 1827 ASSERT(ToRegister(instr->context()).is(esi)); |
| 1828 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 1828 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
| 1829 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1829 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 1830 | 1830 |
| 1831 NearLabel true_value, done; | 1831 NearLabel true_value, done; |
| 1832 __ test(eax, Operand(eax)); | 1832 __ test(eax, Operand(eax)); |
| 1833 __ j(zero, &true_value); | 1833 __ j(zero, &true_value); |
| 1834 __ mov(ToRegister(instr->result()), FACTORY->false_value()); | 1834 __ mov(ToRegister(instr->result()), factory()->false_value()); |
| 1835 __ jmp(&done); | 1835 __ jmp(&done); |
| 1836 __ bind(&true_value); | 1836 __ bind(&true_value); |
| 1837 __ mov(ToRegister(instr->result()), FACTORY->true_value()); | 1837 __ mov(ToRegister(instr->result()), factory()->true_value()); |
| 1838 __ bind(&done); | 1838 __ bind(&done); |
| 1839 } | 1839 } |
| 1840 | 1840 |
| 1841 | 1841 |
| 1842 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 1842 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { |
| 1843 ASSERT(ToRegister(instr->context()).is(esi)); | 1843 ASSERT(ToRegister(instr->context()).is(esi)); |
| 1844 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1844 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1845 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1845 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1846 | 1846 |
| 1847 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 1847 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 __ test(object, Immediate(kSmiTagMask)); | 1879 __ test(object, Immediate(kSmiTagMask)); |
| 1880 __ j(zero, &false_result, not_taken); | 1880 __ j(zero, &false_result, not_taken); |
| 1881 | 1881 |
| 1882 // This is the inlined call site instanceof cache. The two occurences of the | 1882 // This is the inlined call site instanceof cache. The two occurences of the |
| 1883 // hole value will be patched to the last map/result pair generated by the | 1883 // hole value will be patched to the last map/result pair generated by the |
| 1884 // instanceof stub. | 1884 // instanceof stub. |
| 1885 NearLabel cache_miss; | 1885 NearLabel cache_miss; |
| 1886 Register map = ToRegister(instr->TempAt(0)); | 1886 Register map = ToRegister(instr->TempAt(0)); |
| 1887 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); | 1887 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); |
| 1888 __ bind(deferred->map_check()); // Label for calculating code patching. | 1888 __ bind(deferred->map_check()); // Label for calculating code patching. |
| 1889 __ cmp(map, FACTORY->the_hole_value()); // Patched to cached map. | 1889 __ cmp(map, factory()->the_hole_value()); // Patched to cached map. |
| 1890 __ j(not_equal, &cache_miss, not_taken); | 1890 __ j(not_equal, &cache_miss, not_taken); |
| 1891 __ mov(eax, FACTORY->the_hole_value()); // Patched to either true or false. | 1891 __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. |
| 1892 __ jmp(&done); | 1892 __ jmp(&done); |
| 1893 | 1893 |
| 1894 // The inlined call site cache did not match. Check for null and string | 1894 // The inlined call site cache did not match. Check for null and string |
| 1895 // before calling the deferred code. | 1895 // before calling the deferred code. |
| 1896 __ bind(&cache_miss); | 1896 __ bind(&cache_miss); |
| 1897 // Null is not an instance of anything. | 1897 // Null is not an instance of anything. |
| 1898 __ cmp(object, FACTORY->null_value()); | 1898 __ cmp(object, factory()->null_value()); |
| 1899 __ j(equal, &false_result); | 1899 __ j(equal, &false_result); |
| 1900 | 1900 |
| 1901 // String values are not instances of anything. | 1901 // String values are not instances of anything. |
| 1902 Condition is_string = masm_->IsObjectStringType(object, temp, temp); | 1902 Condition is_string = masm_->IsObjectStringType(object, temp, temp); |
| 1903 __ j(is_string, &false_result); | 1903 __ j(is_string, &false_result); |
| 1904 | 1904 |
| 1905 // Go to the deferred code. | 1905 // Go to the deferred code. |
| 1906 __ jmp(deferred->entry()); | 1906 __ jmp(deferred->entry()); |
| 1907 | 1907 |
| 1908 __ bind(&false_result); | 1908 __ bind(&false_result); |
| 1909 __ mov(ToRegister(instr->result()), FACTORY->false_value()); | 1909 __ mov(ToRegister(instr->result()), factory()->false_value()); |
| 1910 | 1910 |
| 1911 // Here result has either true or false. Deferred code also produces true or | 1911 // Here result has either true or false. Deferred code also produces true or |
| 1912 // false object. | 1912 // false object. |
| 1913 __ bind(deferred->exit()); | 1913 __ bind(deferred->exit()); |
| 1914 __ bind(&done); | 1914 __ bind(&done); |
| 1915 } | 1915 } |
| 1916 | 1916 |
| 1917 | 1917 |
| 1918 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 1918 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
| 1919 Label* map_check) { | 1919 Label* map_check) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1971 Handle<Code> ic = CompareIC::GetUninitialized(op); | 1971 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 1972 CallCode(ic, RelocInfo::CODE_TARGET, instr, false); | 1972 CallCode(ic, RelocInfo::CODE_TARGET, instr, false); |
| 1973 | 1973 |
| 1974 Condition condition = ComputeCompareCondition(op); | 1974 Condition condition = ComputeCompareCondition(op); |
| 1975 if (op == Token::GT || op == Token::LTE) { | 1975 if (op == Token::GT || op == Token::LTE) { |
| 1976 condition = ReverseCondition(condition); | 1976 condition = ReverseCondition(condition); |
| 1977 } | 1977 } |
| 1978 NearLabel true_value, done; | 1978 NearLabel true_value, done; |
| 1979 __ test(eax, Operand(eax)); | 1979 __ test(eax, Operand(eax)); |
| 1980 __ j(condition, &true_value); | 1980 __ j(condition, &true_value); |
| 1981 __ mov(ToRegister(instr->result()), FACTORY->false_value()); | 1981 __ mov(ToRegister(instr->result()), factory()->false_value()); |
| 1982 __ jmp(&done); | 1982 __ jmp(&done); |
| 1983 __ bind(&true_value); | 1983 __ bind(&true_value); |
| 1984 __ mov(ToRegister(instr->result()), FACTORY->true_value()); | 1984 __ mov(ToRegister(instr->result()), factory()->true_value()); |
| 1985 __ bind(&done); | 1985 __ bind(&done); |
| 1986 } | 1986 } |
| 1987 | 1987 |
| 1988 | 1988 |
| 1989 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { | 1989 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { |
| 1990 Token::Value op = instr->op(); | 1990 Token::Value op = instr->op(); |
| 1991 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1991 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1992 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1992 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1993 | 1993 |
| 1994 Handle<Code> ic = CompareIC::GetUninitialized(op); | 1994 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2018 __ mov(esp, ebp); | 2018 __ mov(esp, ebp); |
| 2019 __ pop(ebp); | 2019 __ pop(ebp); |
| 2020 __ Ret((ParameterCount() + 1) * kPointerSize, ecx); | 2020 __ Ret((ParameterCount() + 1) * kPointerSize, ecx); |
| 2021 } | 2021 } |
| 2022 | 2022 |
| 2023 | 2023 |
| 2024 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { | 2024 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { |
| 2025 Register result = ToRegister(instr->result()); | 2025 Register result = ToRegister(instr->result()); |
| 2026 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); | 2026 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); |
| 2027 if (instr->hydrogen()->check_hole_value()) { | 2027 if (instr->hydrogen()->check_hole_value()) { |
| 2028 __ cmp(result, FACTORY->the_hole_value()); | 2028 __ cmp(result, factory()->the_hole_value()); |
| 2029 DeoptimizeIf(equal, instr->environment()); | 2029 DeoptimizeIf(equal, instr->environment()); |
| 2030 } | 2030 } |
| 2031 } | 2031 } |
| 2032 | 2032 |
| 2033 | 2033 |
| 2034 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { | 2034 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { |
| 2035 Register value = ToRegister(instr->InputAt(0)); | 2035 Register value = ToRegister(instr->InputAt(0)); |
| 2036 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell()); | 2036 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell()); |
| 2037 | 2037 |
| 2038 // If the cell we are storing to contains the hole it could have | 2038 // If the cell we are storing to contains the hole it could have |
| 2039 // been deleted from the property dictionary. In that case, we need | 2039 // been deleted from the property dictionary. In that case, we need |
| 2040 // to update the property details in the property dictionary to mark | 2040 // to update the property details in the property dictionary to mark |
| 2041 // it as no longer deleted. We deoptimize in that case. | 2041 // it as no longer deleted. We deoptimize in that case. |
| 2042 if (instr->hydrogen()->check_hole_value()) { | 2042 if (instr->hydrogen()->check_hole_value()) { |
| 2043 __ cmp(cell_operand, FACTORY->the_hole_value()); | 2043 __ cmp(cell_operand, factory()->the_hole_value()); |
| 2044 DeoptimizeIf(equal, instr->environment()); | 2044 DeoptimizeIf(equal, instr->environment()); |
| 2045 } | 2045 } |
| 2046 | 2046 |
| 2047 // Store the value. | 2047 // Store the value. |
| 2048 __ mov(cell_operand, value); | 2048 __ mov(cell_operand, value); |
| 2049 } | 2049 } |
| 2050 | 2050 |
| 2051 | 2051 |
| 2052 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2052 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2053 Register context = ToRegister(instr->context()); | 2053 Register context = ToRegister(instr->context()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2079 } | 2079 } |
| 2080 } | 2080 } |
| 2081 | 2081 |
| 2082 | 2082 |
| 2083 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 2083 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 2084 ASSERT(ToRegister(instr->context()).is(esi)); | 2084 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2085 ASSERT(ToRegister(instr->object()).is(eax)); | 2085 ASSERT(ToRegister(instr->object()).is(eax)); |
| 2086 ASSERT(ToRegister(instr->result()).is(eax)); | 2086 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2087 | 2087 |
| 2088 __ mov(ecx, instr->name()); | 2088 __ mov(ecx, instr->name()); |
| 2089 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2089 Handle<Code> ic(isolate()->builtins()->builtin(Builtins::LoadIC_Initialize)); |
| 2090 Builtins::LoadIC_Initialize)); | |
| 2091 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2090 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2092 } | 2091 } |
| 2093 | 2092 |
| 2094 | 2093 |
| 2095 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 2094 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 2096 Register function = ToRegister(instr->function()); | 2095 Register function = ToRegister(instr->function()); |
| 2097 Register temp = ToRegister(instr->TempAt(0)); | 2096 Register temp = ToRegister(instr->TempAt(0)); |
| 2098 Register result = ToRegister(instr->result()); | 2097 Register result = ToRegister(instr->result()); |
| 2099 | 2098 |
| 2100 // Check that the function really is a function. | 2099 // Check that the function really is a function. |
| 2101 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); | 2100 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); |
| 2102 DeoptimizeIf(not_equal, instr->environment()); | 2101 DeoptimizeIf(not_equal, instr->environment()); |
| 2103 | 2102 |
| 2104 // Check whether the function has an instance prototype. | 2103 // Check whether the function has an instance prototype. |
| 2105 NearLabel non_instance; | 2104 NearLabel non_instance; |
| 2106 __ test_b(FieldOperand(result, Map::kBitFieldOffset), | 2105 __ test_b(FieldOperand(result, Map::kBitFieldOffset), |
| 2107 1 << Map::kHasNonInstancePrototype); | 2106 1 << Map::kHasNonInstancePrototype); |
| 2108 __ j(not_zero, &non_instance); | 2107 __ j(not_zero, &non_instance); |
| 2109 | 2108 |
| 2110 // Get the prototype or initial map from the function. | 2109 // Get the prototype or initial map from the function. |
| 2111 __ mov(result, | 2110 __ mov(result, |
| 2112 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 2111 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2113 | 2112 |
| 2114 // Check that the function has a prototype or an initial map. | 2113 // Check that the function has a prototype or an initial map. |
| 2115 __ cmp(Operand(result), Immediate(FACTORY->the_hole_value())); | 2114 __ cmp(Operand(result), Immediate(factory()->the_hole_value())); |
| 2116 DeoptimizeIf(equal, instr->environment()); | 2115 DeoptimizeIf(equal, instr->environment()); |
| 2117 | 2116 |
| 2118 // If the function does not have an initial map, we're done. | 2117 // If the function does not have an initial map, we're done. |
| 2119 NearLabel done; | 2118 NearLabel done; |
| 2120 __ CmpObjectType(result, MAP_TYPE, temp); | 2119 __ CmpObjectType(result, MAP_TYPE, temp); |
| 2121 __ j(not_equal, &done); | 2120 __ j(not_equal, &done); |
| 2122 | 2121 |
| 2123 // Get the prototype from the initial map. | 2122 // Get the prototype from the initial map. |
| 2124 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); | 2123 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); |
| 2125 __ jmp(&done); | 2124 __ jmp(&done); |
| 2126 | 2125 |
| 2127 // Non-instance prototype: Fetch prototype from constructor field | 2126 // Non-instance prototype: Fetch prototype from constructor field |
| 2128 // in the function's map. | 2127 // in the function's map. |
| 2129 __ bind(&non_instance); | 2128 __ bind(&non_instance); |
| 2130 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); | 2129 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); |
| 2131 | 2130 |
| 2132 // All done. | 2131 // All done. |
| 2133 __ bind(&done); | 2132 __ bind(&done); |
| 2134 } | 2133 } |
| 2135 | 2134 |
| 2136 | 2135 |
| 2137 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 2136 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
| 2138 Register result = ToRegister(instr->result()); | 2137 Register result = ToRegister(instr->result()); |
| 2139 Register input = ToRegister(instr->InputAt(0)); | 2138 Register input = ToRegister(instr->InputAt(0)); |
| 2140 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); | 2139 __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); |
| 2141 if (FLAG_debug_code) { | 2140 if (FLAG_debug_code) { |
| 2142 NearLabel done; | 2141 NearLabel done; |
| 2143 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2142 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| 2144 Immediate(FACTORY->fixed_array_map())); | 2143 Immediate(factory()->fixed_array_map())); |
| 2145 __ j(equal, &done); | 2144 __ j(equal, &done); |
| 2146 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2145 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| 2147 Immediate(FACTORY->external_pixel_array_map())); | 2146 Immediate(factory()->external_pixel_array_map())); |
| 2148 __ j(equal, &done); | 2147 __ j(equal, &done); |
| 2149 __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2148 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| 2150 Immediate(FACTORY->fixed_cow_array_map())); | 2149 Immediate(factory()->fixed_cow_array_map())); |
| 2151 __ Check(equal, "Check for fast elements or pixel array failed."); | 2150 __ Check(equal, "Check for fast elements or pixel array failed."); |
| 2152 __ bind(&done); | 2151 __ bind(&done); |
| 2153 } | 2152 } |
| 2154 } | 2153 } |
| 2155 | 2154 |
| 2156 | 2155 |
| 2157 void LCodeGen::DoLoadExternalArrayPointer( | 2156 void LCodeGen::DoLoadExternalArrayPointer( |
| 2158 LLoadExternalArrayPointer* instr) { | 2157 LLoadExternalArrayPointer* instr) { |
| 2159 Register result = ToRegister(instr->result()); | 2158 Register result = ToRegister(instr->result()); |
| 2160 Register input = ToRegister(instr->InputAt(0)); | 2159 Register input = ToRegister(instr->InputAt(0)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2184 Register result = ToRegister(instr->result()); | 2183 Register result = ToRegister(instr->result()); |
| 2185 ASSERT(result.is(elements)); | 2184 ASSERT(result.is(elements)); |
| 2186 | 2185 |
| 2187 // Load the result. | 2186 // Load the result. |
| 2188 __ mov(result, FieldOperand(elements, | 2187 __ mov(result, FieldOperand(elements, |
| 2189 key, | 2188 key, |
| 2190 times_pointer_size, | 2189 times_pointer_size, |
| 2191 FixedArray::kHeaderSize)); | 2190 FixedArray::kHeaderSize)); |
| 2192 | 2191 |
| 2193 // Check for the hole value. | 2192 // Check for the hole value. |
| 2194 __ cmp(result, FACTORY->the_hole_value()); | 2193 __ cmp(result, factory()->the_hole_value()); |
| 2195 DeoptimizeIf(equal, instr->environment()); | 2194 DeoptimizeIf(equal, instr->environment()); |
| 2196 } | 2195 } |
| 2197 | 2196 |
| 2198 | 2197 |
| 2199 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { | 2198 void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { |
| 2200 Register external_pointer = ToRegister(instr->external_pointer()); | 2199 Register external_pointer = ToRegister(instr->external_pointer()); |
| 2201 Register key = ToRegister(instr->key()); | 2200 Register key = ToRegister(instr->key()); |
| 2202 Register result = ToRegister(instr->result()); | 2201 Register result = ToRegister(instr->result()); |
| 2203 ASSERT(result.is(external_pointer)); | 2202 ASSERT(result.is(external_pointer)); |
| 2204 | 2203 |
| 2205 // Load the result. | 2204 // Load the result. |
| 2206 __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); | 2205 __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); |
| 2207 } | 2206 } |
| 2208 | 2207 |
| 2209 | 2208 |
| 2210 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2209 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 2211 ASSERT(ToRegister(instr->context()).is(esi)); | 2210 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2212 ASSERT(ToRegister(instr->object()).is(edx)); | 2211 ASSERT(ToRegister(instr->object()).is(edx)); |
| 2213 ASSERT(ToRegister(instr->key()).is(eax)); | 2212 ASSERT(ToRegister(instr->key()).is(eax)); |
| 2214 | 2213 |
| 2215 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2214 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2216 Builtins::KeyedLoadIC_Initialize)); | 2215 Builtins::KeyedLoadIC_Initialize)); |
| 2217 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2216 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2218 } | 2217 } |
| 2219 | 2218 |
| 2220 | 2219 |
| 2221 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 2220 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| 2222 Register result = ToRegister(instr->result()); | 2221 Register result = ToRegister(instr->result()); |
| 2223 | 2222 |
| 2224 // Check for arguments adapter frame. | 2223 // Check for arguments adapter frame. |
| 2225 NearLabel done, adapted; | 2224 NearLabel done, adapted; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2271 Register length = ToRegister(instr->length()); | 2270 Register length = ToRegister(instr->length()); |
| 2272 Register elements = ToRegister(instr->elements()); | 2271 Register elements = ToRegister(instr->elements()); |
| 2273 Register scratch = ToRegister(instr->TempAt(0)); | 2272 Register scratch = ToRegister(instr->TempAt(0)); |
| 2274 ASSERT(receiver.is(eax)); // Used for parameter count. | 2273 ASSERT(receiver.is(eax)); // Used for parameter count. |
| 2275 ASSERT(function.is(edi)); // Required by InvokeFunction. | 2274 ASSERT(function.is(edi)); // Required by InvokeFunction. |
| 2276 ASSERT(ToRegister(instr->result()).is(eax)); | 2275 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2277 | 2276 |
| 2278 // If the receiver is null or undefined, we have to pass the global object | 2277 // If the receiver is null or undefined, we have to pass the global object |
| 2279 // as a receiver. | 2278 // as a receiver. |
| 2280 NearLabel global_object, receiver_ok; | 2279 NearLabel global_object, receiver_ok; |
| 2281 __ cmp(receiver, FACTORY->null_value()); | 2280 __ cmp(receiver, factory()->null_value()); |
| 2282 __ j(equal, &global_object); | 2281 __ j(equal, &global_object); |
| 2283 __ cmp(receiver, FACTORY->undefined_value()); | 2282 __ cmp(receiver, factory()->undefined_value()); |
| 2284 __ j(equal, &global_object); | 2283 __ j(equal, &global_object); |
| 2285 | 2284 |
| 2286 // The receiver should be a JS object. | 2285 // The receiver should be a JS object. |
| 2287 __ test(receiver, Immediate(kSmiTagMask)); | 2286 __ test(receiver, Immediate(kSmiTagMask)); |
| 2288 DeoptimizeIf(equal, instr->environment()); | 2287 DeoptimizeIf(equal, instr->environment()); |
| 2289 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch); | 2288 __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch); |
| 2290 DeoptimizeIf(below, instr->environment()); | 2289 DeoptimizeIf(below, instr->environment()); |
| 2291 __ jmp(&receiver_ok); | 2290 __ jmp(&receiver_ok); |
| 2292 | 2291 |
| 2293 __ bind(&global_object); | 2292 __ bind(&global_object); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2410 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 2412 ASSERT(ToRegister(instr->result()).is(eax)); | 2411 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2413 __ mov(edi, instr->function()); | 2412 __ mov(edi, instr->function()); |
| 2414 CallKnownFunction(instr->function(), instr->arity(), instr); | 2413 CallKnownFunction(instr->function(), instr->arity(), instr); |
| 2415 } | 2414 } |
| 2416 | 2415 |
| 2417 | 2416 |
| 2418 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2417 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2419 Register input_reg = ToRegister(instr->InputAt(0)); | 2418 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2420 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 2419 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 2421 FACTORY->heap_number_map()); | 2420 factory()->heap_number_map()); |
| 2422 DeoptimizeIf(not_equal, instr->environment()); | 2421 DeoptimizeIf(not_equal, instr->environment()); |
| 2423 | 2422 |
| 2424 Label done; | 2423 Label done; |
| 2425 Register tmp = input_reg.is(eax) ? ecx : eax; | 2424 Register tmp = input_reg.is(eax) ? ecx : eax; |
| 2426 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; | 2425 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; |
| 2427 | 2426 |
| 2428 // Preserve the value of all registers. | 2427 // Preserve the value of all registers. |
| 2429 __ PushSafepointRegisters(); | 2428 __ PushSafepointRegisters(); |
| 2430 | 2429 |
| 2431 Label negative; | 2430 Label negative; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2706 } | 2705 } |
| 2707 } | 2706 } |
| 2708 | 2707 |
| 2709 | 2708 |
| 2710 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 2709 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
| 2711 ASSERT(ToRegister(instr->context()).is(esi)); | 2710 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2712 ASSERT(ToRegister(instr->key()).is(ecx)); | 2711 ASSERT(ToRegister(instr->key()).is(ecx)); |
| 2713 ASSERT(ToRegister(instr->result()).is(eax)); | 2712 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2714 | 2713 |
| 2715 int arity = instr->arity(); | 2714 int arity = instr->arity(); |
| 2716 Handle<Code> ic = Isolate::Current()->stub_cache()-> | 2715 Handle<Code> ic = isolate()->stub_cache()-> |
| 2717 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 2716 ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); |
| 2718 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2717 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2719 } | 2718 } |
| 2720 | 2719 |
| 2721 | 2720 |
| 2722 void LCodeGen::DoCallNamed(LCallNamed* instr) { | 2721 void LCodeGen::DoCallNamed(LCallNamed* instr) { |
| 2723 ASSERT(ToRegister(instr->context()).is(esi)); | 2722 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2724 ASSERT(ToRegister(instr->result()).is(eax)); | 2723 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2725 | 2724 |
| 2726 int arity = instr->arity(); | 2725 int arity = instr->arity(); |
| 2727 Handle<Code> ic = Isolate::Current()->stub_cache()-> | 2726 Handle<Code> ic = isolate()->stub_cache()-> |
| 2728 ComputeCallInitialize(arity, NOT_IN_LOOP); | 2727 ComputeCallInitialize(arity, NOT_IN_LOOP); |
| 2729 __ mov(ecx, instr->name()); | 2728 __ mov(ecx, instr->name()); |
| 2730 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2729 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2731 } | 2730 } |
| 2732 | 2731 |
| 2733 | 2732 |
| 2734 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 2733 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
| 2735 ASSERT(ToRegister(instr->context()).is(esi)); | 2734 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2736 ASSERT(ToRegister(instr->result()).is(eax)); | 2735 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2737 | 2736 |
| 2738 int arity = instr->arity(); | 2737 int arity = instr->arity(); |
| 2739 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 2738 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); |
| 2740 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 2739 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 2741 __ Drop(1); | 2740 __ Drop(1); |
| 2742 } | 2741 } |
| 2743 | 2742 |
| 2744 | 2743 |
| 2745 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 2744 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
| 2746 ASSERT(ToRegister(instr->context()).is(esi)); | 2745 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2747 ASSERT(ToRegister(instr->result()).is(eax)); | 2746 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2748 | 2747 |
| 2749 int arity = instr->arity(); | 2748 int arity = instr->arity(); |
| 2750 Handle<Code> ic = Isolate::Current()->stub_cache()-> | 2749 Handle<Code> ic = isolate()->stub_cache()-> |
| 2751 ComputeCallInitialize(arity, NOT_IN_LOOP); | 2750 ComputeCallInitialize(arity, NOT_IN_LOOP); |
| 2752 __ mov(ecx, instr->name()); | 2751 __ mov(ecx, instr->name()); |
| 2753 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2752 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2754 } | 2753 } |
| 2755 | 2754 |
| 2756 | 2755 |
| 2757 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 2756 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 2758 ASSERT(ToRegister(instr->result()).is(eax)); | 2757 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2759 __ mov(edi, instr->target()); | 2758 __ mov(edi, instr->target()); |
| 2760 CallKnownFunction(instr->target(), instr->arity(), instr); | 2759 CallKnownFunction(instr->target(), instr->arity(), instr); |
| 2761 } | 2760 } |
| 2762 | 2761 |
| 2763 | 2762 |
| 2764 void LCodeGen::DoCallNew(LCallNew* instr) { | 2763 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 2765 ASSERT(ToRegister(instr->context()).is(esi)); | 2764 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2766 ASSERT(ToRegister(instr->constructor()).is(edi)); | 2765 ASSERT(ToRegister(instr->constructor()).is(edi)); |
| 2767 ASSERT(ToRegister(instr->result()).is(eax)); | 2766 ASSERT(ToRegister(instr->result()).is(eax)); |
| 2768 | 2767 |
| 2769 Handle<Code> builtin(Isolate::Current()->builtins()->builtin( | 2768 Handle<Code> builtin(isolate()->builtins()->builtin( |
| 2770 Builtins::JSConstructCall)); | 2769 Builtins::JSConstructCall)); |
| 2771 __ Set(eax, Immediate(instr->arity())); | 2770 __ Set(eax, Immediate(instr->arity())); |
| 2772 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); | 2771 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
| 2773 } | 2772 } |
| 2774 | 2773 |
| 2775 | 2774 |
| 2776 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 2775 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
| 2777 CallRuntime(instr->function(), instr->arity(), instr, false); | 2776 CallRuntime(instr->function(), instr->arity(), instr, false); |
| 2778 } | 2777 } |
| 2779 | 2778 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2807 } | 2806 } |
| 2808 } | 2807 } |
| 2809 | 2808 |
| 2810 | 2809 |
| 2811 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 2810 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 2812 ASSERT(ToRegister(instr->context()).is(esi)); | 2811 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2813 ASSERT(ToRegister(instr->object()).is(edx)); | 2812 ASSERT(ToRegister(instr->object()).is(edx)); |
| 2814 ASSERT(ToRegister(instr->value()).is(eax)); | 2813 ASSERT(ToRegister(instr->value()).is(eax)); |
| 2815 | 2814 |
| 2816 __ mov(ecx, instr->name()); | 2815 __ mov(ecx, instr->name()); |
| 2817 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2816 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2818 info_->is_strict() ? Builtins::StoreIC_Initialize_Strict | 2817 info_->is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 2819 : Builtins::StoreIC_Initialize)); | 2818 : Builtins::StoreIC_Initialize)); |
| 2820 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2819 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2821 } | 2820 } |
| 2822 | 2821 |
| 2823 | 2822 |
| 2824 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 2823 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
| 2825 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); | 2824 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); |
| 2826 DeoptimizeIf(above_equal, instr->environment()); | 2825 DeoptimizeIf(above_equal, instr->environment()); |
| 2827 } | 2826 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2877 } | 2876 } |
| 2878 } | 2877 } |
| 2879 | 2878 |
| 2880 | 2879 |
| 2881 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 2880 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 2882 ASSERT(ToRegister(instr->context()).is(esi)); | 2881 ASSERT(ToRegister(instr->context()).is(esi)); |
| 2883 ASSERT(ToRegister(instr->object()).is(edx)); | 2882 ASSERT(ToRegister(instr->object()).is(edx)); |
| 2884 ASSERT(ToRegister(instr->key()).is(ecx)); | 2883 ASSERT(ToRegister(instr->key()).is(ecx)); |
| 2885 ASSERT(ToRegister(instr->value()).is(eax)); | 2884 ASSERT(ToRegister(instr->value()).is(eax)); |
| 2886 | 2885 |
| 2887 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2886 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2888 info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 2887 info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 2889 : Builtins::KeyedStoreIC_Initialize)); | 2888 : Builtins::KeyedStoreIC_Initialize)); |
| 2890 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2889 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2891 } | 2890 } |
| 2892 | 2891 |
| 2893 | 2892 |
| 2894 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 2893 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 2895 class DeferredStringCharCodeAt: public LDeferredCode { | 2894 class DeferredStringCharCodeAt: public LDeferredCode { |
| 2896 public: | 2895 public: |
| 2897 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 2896 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2939 // Handle non-flat strings. | 2938 // Handle non-flat strings. |
| 2940 __ test(result, Immediate(kIsConsStringMask)); | 2939 __ test(result, Immediate(kIsConsStringMask)); |
| 2941 __ j(zero, deferred->entry()); | 2940 __ j(zero, deferred->entry()); |
| 2942 | 2941 |
| 2943 // ConsString. | 2942 // ConsString. |
| 2944 // Check whether the right hand side is the empty string (i.e. if | 2943 // Check whether the right hand side is the empty string (i.e. if |
| 2945 // this is really a flat string in a cons string). If that is not | 2944 // this is really a flat string in a cons string). If that is not |
| 2946 // the case we would rather go to the runtime system now to flatten | 2945 // the case we would rather go to the runtime system now to flatten |
| 2947 // the string. | 2946 // the string. |
| 2948 __ cmp(FieldOperand(string, ConsString::kSecondOffset), | 2947 __ cmp(FieldOperand(string, ConsString::kSecondOffset), |
| 2949 Immediate(FACTORY->empty_string())); | 2948 Immediate(factory()->empty_string())); |
| 2950 __ j(not_equal, deferred->entry()); | 2949 __ j(not_equal, deferred->entry()); |
| 2951 // Get the first of the two strings and load its instance type. | 2950 // Get the first of the two strings and load its instance type. |
| 2952 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); | 2951 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); |
| 2953 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); | 2952 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 2954 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 2953 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 2955 // If the first cons component is also non-flat, then go to runtime. | 2954 // If the first cons component is also non-flat, then go to runtime. |
| 2956 STATIC_ASSERT(kSeqStringTag == 0); | 2955 STATIC_ASSERT(kSeqStringTag == 0); |
| 2957 __ test(result, Immediate(kStringRepresentationMask)); | 2956 __ test(result, Immediate(kStringRepresentationMask)); |
| 2958 __ j(not_zero, deferred->entry()); | 2957 __ j(not_zero, deferred->entry()); |
| 2959 | 2958 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 DeferredStringCharFromCode* deferred = | 3043 DeferredStringCharFromCode* deferred = |
| 3045 new DeferredStringCharFromCode(this, instr); | 3044 new DeferredStringCharFromCode(this, instr); |
| 3046 | 3045 |
| 3047 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); | 3046 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
| 3048 Register char_code = ToRegister(instr->char_code()); | 3047 Register char_code = ToRegister(instr->char_code()); |
| 3049 Register result = ToRegister(instr->result()); | 3048 Register result = ToRegister(instr->result()); |
| 3050 ASSERT(!char_code.is(result)); | 3049 ASSERT(!char_code.is(result)); |
| 3051 | 3050 |
| 3052 __ cmp(char_code, String::kMaxAsciiCharCode); | 3051 __ cmp(char_code, String::kMaxAsciiCharCode); |
| 3053 __ j(above, deferred->entry()); | 3052 __ j(above, deferred->entry()); |
| 3054 __ Set(result, Immediate(FACTORY->single_character_string_cache())); | 3053 __ Set(result, Immediate(factory()->single_character_string_cache())); |
| 3055 __ mov(result, FieldOperand(result, | 3054 __ mov(result, FieldOperand(result, |
| 3056 char_code, times_pointer_size, | 3055 char_code, times_pointer_size, |
| 3057 FixedArray::kHeaderSize)); | 3056 FixedArray::kHeaderSize)); |
| 3058 __ cmp(result, FACTORY->undefined_value()); | 3057 __ cmp(result, factory()->undefined_value()); |
| 3059 __ j(equal, deferred->entry()); | 3058 __ j(equal, deferred->entry()); |
| 3060 __ bind(deferred->exit()); | 3059 __ bind(deferred->exit()); |
| 3061 } | 3060 } |
| 3062 | 3061 |
| 3063 | 3062 |
| 3064 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { | 3063 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
| 3065 Register char_code = ToRegister(instr->char_code()); | 3064 Register char_code = ToRegister(instr->char_code()); |
| 3066 Register result = ToRegister(instr->result()); | 3065 Register result = ToRegister(instr->result()); |
| 3067 | 3066 |
| 3068 // TODO(3095996): Get rid of this. For now, we need to make the | 3067 // TODO(3095996): Get rid of this. For now, we need to make the |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3226 XMMRegister result_reg, | 3225 XMMRegister result_reg, |
| 3227 LEnvironment* env) { | 3226 LEnvironment* env) { |
| 3228 NearLabel load_smi, heap_number, done; | 3227 NearLabel load_smi, heap_number, done; |
| 3229 | 3228 |
| 3230 // Smi check. | 3229 // Smi check. |
| 3231 __ test(input_reg, Immediate(kSmiTagMask)); | 3230 __ test(input_reg, Immediate(kSmiTagMask)); |
| 3232 __ j(zero, &load_smi, not_taken); | 3231 __ j(zero, &load_smi, not_taken); |
| 3233 | 3232 |
| 3234 // Heap number map check. | 3233 // Heap number map check. |
| 3235 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3234 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3236 FACTORY->heap_number_map()); | 3235 factory()->heap_number_map()); |
| 3237 __ j(equal, &heap_number); | 3236 __ j(equal, &heap_number); |
| 3238 | 3237 |
| 3239 __ cmp(input_reg, FACTORY->undefined_value()); | 3238 __ cmp(input_reg, factory()->undefined_value()); |
| 3240 DeoptimizeIf(not_equal, env); | 3239 DeoptimizeIf(not_equal, env); |
| 3241 | 3240 |
| 3242 // Convert undefined to NaN. | 3241 // Convert undefined to NaN. |
| 3243 __ push(input_reg); | 3242 __ push(input_reg); |
| 3244 __ mov(input_reg, FACTORY->nan_value()); | 3243 __ mov(input_reg, factory()->nan_value()); |
| 3245 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3244 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3246 __ pop(input_reg); | 3245 __ pop(input_reg); |
| 3247 __ jmp(&done); | 3246 __ jmp(&done); |
| 3248 | 3247 |
| 3249 // Heap number to XMM conversion. | 3248 // Heap number to XMM conversion. |
| 3250 __ bind(&heap_number); | 3249 __ bind(&heap_number); |
| 3251 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3250 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3252 __ jmp(&done); | 3251 __ jmp(&done); |
| 3253 | 3252 |
| 3254 // Smi to XMM conversion | 3253 // Smi to XMM conversion |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3269 LTaggedToI* instr_; | 3268 LTaggedToI* instr_; |
| 3270 }; | 3269 }; |
| 3271 | 3270 |
| 3272 | 3271 |
| 3273 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3272 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
| 3274 NearLabel done, heap_number; | 3273 NearLabel done, heap_number; |
| 3275 Register input_reg = ToRegister(instr->InputAt(0)); | 3274 Register input_reg = ToRegister(instr->InputAt(0)); |
| 3276 | 3275 |
| 3277 // Heap number map check. | 3276 // Heap number map check. |
| 3278 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3277 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3279 FACTORY->heap_number_map()); | 3278 factory()->heap_number_map()); |
| 3280 | 3279 |
| 3281 if (instr->truncating()) { | 3280 if (instr->truncating()) { |
| 3282 __ j(equal, &heap_number); | 3281 __ j(equal, &heap_number); |
| 3283 // Check for undefined. Undefined is converted to zero for truncating | 3282 // Check for undefined. Undefined is converted to zero for truncating |
| 3284 // conversions. | 3283 // conversions. |
| 3285 __ cmp(input_reg, FACTORY->undefined_value()); | 3284 __ cmp(input_reg, factory()->undefined_value()); |
| 3286 DeoptimizeIf(not_equal, instr->environment()); | 3285 DeoptimizeIf(not_equal, instr->environment()); |
| 3287 __ mov(input_reg, 0); | 3286 __ mov(input_reg, 0); |
| 3288 __ jmp(&done); | 3287 __ jmp(&done); |
| 3289 | 3288 |
| 3290 __ bind(&heap_number); | 3289 __ bind(&heap_number); |
| 3291 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) { | 3290 if (isolate()->cpu_features()->IsSupported(SSE3)) { |
| 3292 CpuFeatures::Scope scope(SSE3); | 3291 CpuFeatures::Scope scope(SSE3); |
| 3293 NearLabel convert; | 3292 NearLabel convert; |
| 3294 // Use more powerful conversion when sse3 is available. | 3293 // Use more powerful conversion when sse3 is available. |
| 3295 // Load x87 register with heap number. | 3294 // Load x87 register with heap number. |
| 3296 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3295 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3297 // Get exponent alone and check for too-big exponent. | 3296 // Get exponent alone and check for too-big exponent. |
| 3298 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3297 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 3299 __ and_(input_reg, HeapNumber::kExponentMask); | 3298 __ and_(input_reg, HeapNumber::kExponentMask); |
| 3300 const uint32_t kTooBigExponent = | 3299 const uint32_t kTooBigExponent = |
| 3301 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 3300 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3391 ASSERT(result->IsRegister()); | 3390 ASSERT(result->IsRegister()); |
| 3392 | 3391 |
| 3393 XMMRegister input_reg = ToDoubleRegister(input); | 3392 XMMRegister input_reg = ToDoubleRegister(input); |
| 3394 Register result_reg = ToRegister(result); | 3393 Register result_reg = ToRegister(result); |
| 3395 | 3394 |
| 3396 if (instr->truncating()) { | 3395 if (instr->truncating()) { |
| 3397 // Performs a truncating conversion of a floating point number as used by | 3396 // Performs a truncating conversion of a floating point number as used by |
| 3398 // the JS bitwise operations. | 3397 // the JS bitwise operations. |
| 3399 __ cvttsd2si(result_reg, Operand(input_reg)); | 3398 __ cvttsd2si(result_reg, Operand(input_reg)); |
| 3400 __ cmp(result_reg, 0x80000000u); | 3399 __ cmp(result_reg, 0x80000000u); |
| 3401 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) { | 3400 if (isolate()->cpu_features()->IsSupported(SSE3)) { |
| 3402 // This will deoptimize if the exponent of the input in out of range. | 3401 // This will deoptimize if the exponent of the input in out of range. |
| 3403 CpuFeatures::Scope scope(SSE3); | 3402 CpuFeatures::Scope scope(SSE3); |
| 3404 NearLabel convert, done; | 3403 NearLabel convert, done; |
| 3405 __ j(not_equal, &done); | 3404 __ j(not_equal, &done); |
| 3406 __ sub(Operand(esp), Immediate(kDoubleSize)); | 3405 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 3407 __ movdbl(Operand(esp, 0), input_reg); | 3406 __ movdbl(Operand(esp, 0), input_reg); |
| 3408 // Get exponent alone and check for too-big exponent. | 3407 // Get exponent alone and check for too-big exponent. |
| 3409 __ mov(result_reg, Operand(esp, sizeof(int32_t))); | 3408 __ mov(result_reg, Operand(esp, sizeof(int32_t))); |
| 3410 __ and_(result_reg, HeapNumber::kExponentMask); | 3409 __ and_(result_reg, HeapNumber::kExponentMask); |
| 3411 const uint32_t kTooBigExponent = | 3410 const uint32_t kTooBigExponent = |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3552 LOperand* input = instr->InputAt(0); | 3551 LOperand* input = instr->InputAt(0); |
| 3553 ASSERT(input->IsRegister()); | 3552 ASSERT(input->IsRegister()); |
| 3554 Register reg = ToRegister(input); | 3553 Register reg = ToRegister(input); |
| 3555 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 3554 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 3556 instr->hydrogen()->map()); | 3555 instr->hydrogen()->map()); |
| 3557 DeoptimizeIf(not_equal, instr->environment()); | 3556 DeoptimizeIf(not_equal, instr->environment()); |
| 3558 } | 3557 } |
| 3559 | 3558 |
| 3560 | 3559 |
| 3561 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | 3560 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { |
| 3562 if (HEAP->InNewSpace(*object)) { | 3561 if (isolate()->heap()->InNewSpace(*object)) { |
| 3563 Handle<JSGlobalPropertyCell> cell = | 3562 Handle<JSGlobalPropertyCell> cell = |
| 3564 FACTORY->NewJSGlobalPropertyCell(object); | 3563 isolate()->factory()->NewJSGlobalPropertyCell(object); |
| 3565 __ mov(result, Operand::Cell(cell)); | 3564 __ mov(result, Operand::Cell(cell)); |
| 3566 } else { | 3565 } else { |
| 3567 __ mov(result, object); | 3566 __ mov(result, object); |
| 3568 } | 3567 } |
| 3569 } | 3568 } |
| 3570 | 3569 |
| 3571 | 3570 |
| 3572 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 3571 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 3573 Register reg = ToRegister(instr->TempAt(0)); | 3572 Register reg = ToRegister(instr->TempAt(0)); |
| 3574 | 3573 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 // Registers will be used as follows: | 3646 // Registers will be used as follows: |
| 3648 // edi = JS function. | 3647 // edi = JS function. |
| 3649 // ecx = literals array. | 3648 // ecx = literals array. |
| 3650 // ebx = regexp literal. | 3649 // ebx = regexp literal. |
| 3651 // eax = regexp literal clone. | 3650 // eax = regexp literal clone. |
| 3652 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3651 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3653 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 3652 __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
| 3654 int literal_offset = FixedArray::kHeaderSize + | 3653 int literal_offset = FixedArray::kHeaderSize + |
| 3655 instr->hydrogen()->literal_index() * kPointerSize; | 3654 instr->hydrogen()->literal_index() * kPointerSize; |
| 3656 __ mov(ebx, FieldOperand(ecx, literal_offset)); | 3655 __ mov(ebx, FieldOperand(ecx, literal_offset)); |
| 3657 __ cmp(ebx, FACTORY->undefined_value()); | 3656 __ cmp(ebx, factory()->undefined_value()); |
| 3658 __ j(not_equal, &materialized); | 3657 __ j(not_equal, &materialized); |
| 3659 | 3658 |
| 3660 // Create regexp literal using runtime function | 3659 // Create regexp literal using runtime function |
| 3661 // Result will be in eax. | 3660 // Result will be in eax. |
| 3662 __ push(ecx); | 3661 __ push(ecx); |
| 3663 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 3662 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| 3664 __ push(Immediate(instr->hydrogen()->pattern())); | 3663 __ push(Immediate(instr->hydrogen()->pattern())); |
| 3665 __ push(Immediate(instr->hydrogen()->flags())); | 3664 __ push(Immediate(instr->hydrogen()->flags())); |
| 3666 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, false); | 3665 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, false); |
| 3667 __ mov(ebx, eax); | 3666 __ mov(ebx, eax); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3700 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | 3699 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); |
| 3701 bool pretenure = instr->hydrogen()->pretenure(); | 3700 bool pretenure = instr->hydrogen()->pretenure(); |
| 3702 if (shared_info->num_literals() == 0 && !pretenure) { | 3701 if (shared_info->num_literals() == 0 && !pretenure) { |
| 3703 FastNewClosureStub stub; | 3702 FastNewClosureStub stub; |
| 3704 __ push(Immediate(shared_info)); | 3703 __ push(Immediate(shared_info)); |
| 3705 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 3704 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); |
| 3706 } else { | 3705 } else { |
| 3707 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); | 3706 __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3708 __ push(Immediate(shared_info)); | 3707 __ push(Immediate(shared_info)); |
| 3709 __ push(Immediate(pretenure | 3708 __ push(Immediate(pretenure |
| 3710 ? FACTORY->true_value() | 3709 ? factory()->true_value() |
| 3711 : FACTORY->false_value())); | 3710 : factory()->false_value())); |
| 3712 CallRuntime(Runtime::kNewClosure, 3, instr, false); | 3711 CallRuntime(Runtime::kNewClosure, 3, instr, false); |
| 3713 } | 3712 } |
| 3714 } | 3713 } |
| 3715 | 3714 |
| 3716 | 3715 |
| 3717 void LCodeGen::DoTypeof(LTypeof* instr) { | 3716 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 3718 LOperand* input = instr->InputAt(0); | 3717 LOperand* input = instr->InputAt(0); |
| 3719 if (input->IsConstantOperand()) { | 3718 if (input->IsConstantOperand()) { |
| 3720 __ push(ToImmediate(input)); | 3719 __ push(ToImmediate(input)); |
| 3721 } else { | 3720 } else { |
| 3722 __ push(ToOperand(input)); | 3721 __ push(ToOperand(input)); |
| 3723 } | 3722 } |
| 3724 CallRuntime(Runtime::kTypeof, 1, instr, false); | 3723 CallRuntime(Runtime::kTypeof, 1, instr, false); |
| 3725 } | 3724 } |
| 3726 | 3725 |
| 3727 | 3726 |
| 3728 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { | 3727 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { |
| 3729 Register input = ToRegister(instr->InputAt(0)); | 3728 Register input = ToRegister(instr->InputAt(0)); |
| 3730 Register result = ToRegister(instr->result()); | 3729 Register result = ToRegister(instr->result()); |
| 3731 Label true_label; | 3730 Label true_label; |
| 3732 Label false_label; | 3731 Label false_label; |
| 3733 NearLabel done; | 3732 NearLabel done; |
| 3734 | 3733 |
| 3735 Condition final_branch_condition = EmitTypeofIs(&true_label, | 3734 Condition final_branch_condition = EmitTypeofIs(&true_label, |
| 3736 &false_label, | 3735 &false_label, |
| 3737 input, | 3736 input, |
| 3738 instr->type_literal()); | 3737 instr->type_literal()); |
| 3739 __ j(final_branch_condition, &true_label); | 3738 __ j(final_branch_condition, &true_label); |
| 3740 __ bind(&false_label); | 3739 __ bind(&false_label); |
| 3741 __ mov(result, FACTORY->false_value()); | 3740 __ mov(result, factory()->false_value()); |
| 3742 __ jmp(&done); | 3741 __ jmp(&done); |
| 3743 | 3742 |
| 3744 __ bind(&true_label); | 3743 __ bind(&true_label); |
| 3745 __ mov(result, FACTORY->true_value()); | 3744 __ mov(result, factory()->true_value()); |
| 3746 | 3745 |
| 3747 __ bind(&done); | 3746 __ bind(&done); |
| 3748 } | 3747 } |
| 3749 | 3748 |
| 3750 | 3749 |
| 3751 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 3750 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 3752 Register input = ToRegister(instr->InputAt(0)); | 3751 Register input = ToRegister(instr->InputAt(0)); |
| 3753 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 3752 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 3754 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 3753 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 3755 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 3754 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 3756 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 3755 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 3757 | 3756 |
| 3758 Condition final_branch_condition = EmitTypeofIs(true_label, | 3757 Condition final_branch_condition = EmitTypeofIs(true_label, |
| 3759 false_label, | 3758 false_label, |
| 3760 input, | 3759 input, |
| 3761 instr->type_literal()); | 3760 instr->type_literal()); |
| 3762 | 3761 |
| 3763 EmitBranch(true_block, false_block, final_branch_condition); | 3762 EmitBranch(true_block, false_block, final_branch_condition); |
| 3764 } | 3763 } |
| 3765 | 3764 |
| 3766 | 3765 |
| 3767 Condition LCodeGen::EmitTypeofIs(Label* true_label, | 3766 Condition LCodeGen::EmitTypeofIs(Label* true_label, |
| 3768 Label* false_label, | 3767 Label* false_label, |
| 3769 Register input, | 3768 Register input, |
| 3770 Handle<String> type_name) { | 3769 Handle<String> type_name) { |
| 3771 Condition final_branch_condition = no_condition; | 3770 Condition final_branch_condition = no_condition; |
| 3772 if (type_name->Equals(HEAP->number_symbol())) { | 3771 if (type_name->Equals(heap()->number_symbol())) { |
| 3773 __ JumpIfSmi(input, true_label); | 3772 __ JumpIfSmi(input, true_label); |
| 3774 __ cmp(FieldOperand(input, HeapObject::kMapOffset), | 3773 __ cmp(FieldOperand(input, HeapObject::kMapOffset), |
| 3775 FACTORY->heap_number_map()); | 3774 factory()->heap_number_map()); |
| 3776 final_branch_condition = equal; | 3775 final_branch_condition = equal; |
| 3777 | 3776 |
| 3778 } else if (type_name->Equals(HEAP->string_symbol())) { | 3777 } else if (type_name->Equals(heap()->string_symbol())) { |
| 3779 __ JumpIfSmi(input, false_label); | 3778 __ JumpIfSmi(input, false_label); |
| 3780 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); | 3779 __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); |
| 3781 __ j(above_equal, false_label); | 3780 __ j(above_equal, false_label); |
| 3782 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 3781 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 3783 1 << Map::kIsUndetectable); | 3782 1 << Map::kIsUndetectable); |
| 3784 final_branch_condition = zero; | 3783 final_branch_condition = zero; |
| 3785 | 3784 |
| 3786 } else if (type_name->Equals(HEAP->boolean_symbol())) { | 3785 } else if (type_name->Equals(heap()->boolean_symbol())) { |
| 3787 __ cmp(input, FACTORY->true_value()); | 3786 __ cmp(input, factory()->true_value()); |
| 3788 __ j(equal, true_label); | 3787 __ j(equal, true_label); |
| 3789 __ cmp(input, FACTORY->false_value()); | 3788 __ cmp(input, factory()->false_value()); |
| 3790 final_branch_condition = equal; | 3789 final_branch_condition = equal; |
| 3791 | 3790 |
| 3792 } else if (type_name->Equals(HEAP->undefined_symbol())) { | 3791 } else if (type_name->Equals(heap()->undefined_symbol())) { |
| 3793 __ cmp(input, FACTORY->undefined_value()); | 3792 __ cmp(input, factory()->undefined_value()); |
| 3794 __ j(equal, true_label); | 3793 __ j(equal, true_label); |
| 3795 __ JumpIfSmi(input, false_label); | 3794 __ JumpIfSmi(input, false_label); |
| 3796 // Check for undetectable objects => true. | 3795 // Check for undetectable objects => true. |
| 3797 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 3796 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 3798 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 3797 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 3799 1 << Map::kIsUndetectable); | 3798 1 << Map::kIsUndetectable); |
| 3800 final_branch_condition = not_zero; | 3799 final_branch_condition = not_zero; |
| 3801 | 3800 |
| 3802 } else if (type_name->Equals(HEAP->function_symbol())) { | 3801 } else if (type_name->Equals(heap()->function_symbol())) { |
| 3803 __ JumpIfSmi(input, false_label); | 3802 __ JumpIfSmi(input, false_label); |
| 3804 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 3803 __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |
| 3805 __ j(equal, true_label); | 3804 __ j(equal, true_label); |
| 3806 // Regular expressions => 'function' (they are callable). | 3805 // Regular expressions => 'function' (they are callable). |
| 3807 __ CmpInstanceType(input, JS_REGEXP_TYPE); | 3806 __ CmpInstanceType(input, JS_REGEXP_TYPE); |
| 3808 final_branch_condition = equal; | 3807 final_branch_condition = equal; |
| 3809 | 3808 |
| 3810 } else if (type_name->Equals(HEAP->object_symbol())) { | 3809 } else if (type_name->Equals(heap()->object_symbol())) { |
| 3811 __ JumpIfSmi(input, false_label); | 3810 __ JumpIfSmi(input, false_label); |
| 3812 __ cmp(input, FACTORY->null_value()); | 3811 __ cmp(input, factory()->null_value()); |
| 3813 __ j(equal, true_label); | 3812 __ j(equal, true_label); |
| 3814 // Regular expressions => 'function', not 'object'. | 3813 // Regular expressions => 'function', not 'object'. |
| 3815 __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); | 3814 __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input); |
| 3816 __ j(below, false_label); | 3815 __ j(below, false_label); |
| 3817 __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); | 3816 __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE); |
| 3818 __ j(above_equal, false_label); | 3817 __ j(above_equal, false_label); |
| 3819 // Check for undetectable objects => false. | 3818 // Check for undetectable objects => false. |
| 3820 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 3819 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 3821 1 << Map::kIsUndetectable); | 3820 1 << Map::kIsUndetectable); |
| 3822 final_branch_condition = zero; | 3821 final_branch_condition = zero; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3833 | 3832 |
| 3834 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { | 3833 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { |
| 3835 Register result = ToRegister(instr->result()); | 3834 Register result = ToRegister(instr->result()); |
| 3836 NearLabel true_label; | 3835 NearLabel true_label; |
| 3837 NearLabel false_label; | 3836 NearLabel false_label; |
| 3838 NearLabel done; | 3837 NearLabel done; |
| 3839 | 3838 |
| 3840 EmitIsConstructCall(result); | 3839 EmitIsConstructCall(result); |
| 3841 __ j(equal, &true_label); | 3840 __ j(equal, &true_label); |
| 3842 | 3841 |
| 3843 __ mov(result, FACTORY->false_value()); | 3842 __ mov(result, factory()->false_value()); |
| 3844 __ jmp(&done); | 3843 __ jmp(&done); |
| 3845 | 3844 |
| 3846 __ bind(&true_label); | 3845 __ bind(&true_label); |
| 3847 __ mov(result, FACTORY->true_value()); | 3846 __ mov(result, factory()->true_value()); |
| 3848 | 3847 |
| 3849 __ bind(&done); | 3848 __ bind(&done); |
| 3850 } | 3849 } |
| 3851 | 3850 |
| 3852 | 3851 |
| 3853 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 3852 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 3854 Register temp = ToRegister(instr->TempAt(0)); | 3853 Register temp = ToRegister(instr->TempAt(0)); |
| 3855 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 3854 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 3856 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 3855 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 3857 | 3856 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3944 ASSERT(osr_pc_offset_ == -1); | 3943 ASSERT(osr_pc_offset_ == -1); |
| 3945 osr_pc_offset_ = masm()->pc_offset(); | 3944 osr_pc_offset_ = masm()->pc_offset(); |
| 3946 } | 3945 } |
| 3947 | 3946 |
| 3948 | 3947 |
| 3949 #undef __ | 3948 #undef __ |
| 3950 | 3949 |
| 3951 } } // namespace v8::internal | 3950 } } // namespace v8::internal |
| 3952 | 3951 |
| 3953 #endif // V8_TARGET_ARCH_IA32 | 3952 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |