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

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

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 } 1206 }
1207 1207
1208 1208
1209 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1209 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1210 Register result = ToRegister(instr->result()); 1210 Register result = ToRegister(instr->result());
1211 Register array = ToRegister(instr->InputAt(0)); 1211 Register array = ToRegister(instr->InputAt(0));
1212 __ movq(result, FieldOperand(array, JSArray::kLengthOffset)); 1212 __ movq(result, FieldOperand(array, JSArray::kLengthOffset));
1213 } 1213 }
1214 1214
1215 1215
1216 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 1216 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
1217 Register result = ToRegister(instr->result()); 1217 Register result = ToRegister(instr->result());
1218 Register array = ToRegister(instr->InputAt(0)); 1218 Register array = ToRegister(instr->InputAt(0));
1219 __ movq(result, FieldOperand(array, FixedArray::kLengthOffset)); 1219 __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1220 }
1221
1222
1223 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
1224 Register result = ToRegister(instr->result());
1225 Register array = ToRegister(instr->InputAt(0));
1226 __ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
1227 } 1220 }
1228 1221
1229 1222
1230 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1223 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1231 Register result = ToRegister(instr->result()); 1224 Register result = ToRegister(instr->result());
1232 Register input = ToRegister(instr->InputAt(0)); 1225 Register input = ToRegister(instr->InputAt(0));
1233 1226
1234 // Load map into |result|. 1227 // Load map into |result|.
1235 __ movq(result, FieldOperand(input, HeapObject::kMapOffset)); 1228 __ movq(result, FieldOperand(input, HeapObject::kMapOffset));
1236 // Load the map's "bit field 2" into |result|. We only need the first byte. 1229 // Load the map's "bit field 2" into |result|. We only need the first byte.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1393 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1401 1394
1402 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 1395 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1403 // Avoid deopts in the case where we've never executed this path before. 1396 // Avoid deopts in the case where we've never executed this path before.
1404 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 1397 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1405 1398
1406 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 1399 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1407 // undefined -> false. 1400 // undefined -> false.
1408 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); 1401 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1409 __ j(equal, false_label); 1402 __ j(equal, false_label);
1410 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1411 // We've seen undefined for the first time -> deopt.
1412 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1413 DeoptimizeIf(equal, instr->environment());
1414 } 1403 }
1415
1416 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 1404 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1417 // true -> true. 1405 // true -> true.
1418 __ CompareRoot(reg, Heap::kTrueValueRootIndex); 1406 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1419 __ j(equal, true_label); 1407 __ j(equal, true_label);
1420 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1421 // We've seen a boolean for the first time -> deopt.
1422 __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1423 DeoptimizeIf(equal, instr->environment());
1424 }
1425
1426 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1427 // false -> false. 1408 // false -> false.
1428 __ CompareRoot(reg, Heap::kFalseValueRootIndex); 1409 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1429 __ j(equal, false_label); 1410 __ j(equal, false_label);
1430 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1431 // We've seen a boolean for the first time -> deopt.
1432 __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1433 DeoptimizeIf(equal, instr->environment());
1434 } 1411 }
1435
1436 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 1412 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1437 // 'null' -> false. 1413 // 'null' -> false.
1438 __ CompareRoot(reg, Heap::kNullValueRootIndex); 1414 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1439 __ j(equal, false_label); 1415 __ j(equal, false_label);
1440 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1441 // We've seen null for the first time -> deopt.
1442 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1443 DeoptimizeIf(equal, instr->environment());
1444 } 1416 }
1445 1417
1446 if (expected.Contains(ToBooleanStub::SMI)) { 1418 if (expected.Contains(ToBooleanStub::SMI)) {
1447 // Smis: 0 -> false, all other -> true. 1419 // Smis: 0 -> false, all other -> true.
1448 __ Cmp(reg, Smi::FromInt(0)); 1420 __ Cmp(reg, Smi::FromInt(0));
1449 __ j(equal, false_label); 1421 __ j(equal, false_label);
1450 __ JumpIfSmi(reg, true_label); 1422 __ JumpIfSmi(reg, true_label);
1451 } else if (expected.NeedsMap()) { 1423 } else if (expected.NeedsMap()) {
1452 // If we need a map later and have a Smi -> deopt. 1424 // If we need a map later and have a Smi -> deopt.
1453 __ testb(reg, Immediate(kSmiTagMask)); 1425 __ testb(reg, Immediate(kSmiTagMask));
1454 DeoptimizeIf(zero, instr->environment()); 1426 DeoptimizeIf(zero, instr->environment());
1455 } 1427 }
1456 1428
1457 const Register map = kScratchRegister; 1429 const Register map = kScratchRegister;
1458 if (expected.NeedsMap()) { 1430 if (expected.NeedsMap()) {
1459 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset)); 1431 __ movq(map, FieldOperand(reg, HeapObject::kMapOffset));
1460 // Everything with a map could be undetectable, so check this now. 1432
1461 __ testb(FieldOperand(map, Map::kBitFieldOffset), 1433 if (expected.CanBeUndetectable()) {
1462 Immediate(1 << Map::kIsUndetectable)); 1434 // Undetectable -> false.
1463 // Undetectable -> false. 1435 __ testb(FieldOperand(map, Map::kBitFieldOffset),
1464 __ j(not_zero, false_label); 1436 Immediate(1 << Map::kIsUndetectable));
1437 __ j(not_zero, false_label);
1438 }
1465 } 1439 }
1466 1440
1467 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 1441 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1468 // spec object -> true. 1442 // spec object -> true.
1469 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 1443 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1470 __ j(above_equal, true_label); 1444 __ j(above_equal, true_label);
1471 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1472 // We've seen a spec object for the first time -> deopt.
1473 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1474 DeoptimizeIf(above_equal, instr->environment());
1475 } 1445 }
1476 1446
1477 if (expected.Contains(ToBooleanStub::STRING)) { 1447 if (expected.Contains(ToBooleanStub::STRING)) {
1478 // String value -> false iff empty. 1448 // String value -> false iff empty.
1479 Label not_string; 1449 Label not_string;
1480 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 1450 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1481 __ j(above_equal, &not_string, Label::kNear); 1451 __ j(above_equal, &not_string, Label::kNear);
1482 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 1452 __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0));
1483 __ j(not_zero, true_label); 1453 __ j(not_zero, true_label);
1484 __ jmp(false_label); 1454 __ jmp(false_label);
1485 __ bind(&not_string); 1455 __ bind(&not_string);
1486 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1487 // We've seen a string for the first time -> deopt
1488 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1489 DeoptimizeIf(below, instr->environment());
1490 } 1456 }
1491 1457
1492 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 1458 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1493 // heap number -> false iff +0, -0, or NaN. 1459 // heap number -> false iff +0, -0, or NaN.
1494 Label not_heap_number; 1460 Label not_heap_number;
1495 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1461 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1496 __ j(not_equal, &not_heap_number, Label::kNear); 1462 __ j(not_equal, &not_heap_number, Label::kNear);
1497 __ xorps(xmm0, xmm0); 1463 __ xorps(xmm0, xmm0);
1498 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 1464 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
1499 __ j(zero, false_label); 1465 __ j(zero, false_label);
1500 __ jmp(true_label); 1466 __ jmp(true_label);
1501 __ bind(&not_heap_number); 1467 __ bind(&not_heap_number);
1502 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1503 // We've seen a heap number for the first time -> deopt.
1504 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1505 DeoptimizeIf(equal, instr->environment());
1506 } 1468 }
1507 1469
1508 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { 1470 // We've seen something for the first time -> deopt.
1509 // internal objects -> true 1471 DeoptimizeIf(no_condition, instr->environment());
1510 __ jmp(true_label);
1511 } else {
1512 // We've seen something for the first time -> deopt.
1513 DeoptimizeIf(no_condition, instr->environment());
1514 }
1515 } 1472 }
1516 } 1473 }
1517 } 1474 }
1518 1475
1519 1476
1520 void LCodeGen::EmitGoto(int block) { 1477 void LCodeGen::EmitGoto(int block) {
1521 block = chunk_->LookupDestination(block); 1478 block = chunk_->LookupDestination(block);
1522 int next_block = GetNextEmittedBlock(current_block_); 1479 int next_block = GetNextEmittedBlock(current_block_);
1523 if (block != next_block) { 1480 if (block != next_block) {
1524 __ jmp(chunk_->GetAssemblyLabel(block)); 1481 __ jmp(chunk_->GetAssemblyLabel(block));
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
2309 } 2266 }
2310 DeoptimizeIf(below_equal, instr->environment()); 2267 DeoptimizeIf(below_equal, instr->environment());
2311 2268
2312 // There are two words between the frame pointer and the last argument. 2269 // There are two words between the frame pointer and the last argument.
2313 // Subtracting from length accounts for one of them add one more. 2270 // Subtracting from length accounts for one of them add one more.
2314 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); 2271 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
2315 } 2272 }
2316 2273
2317 2274
2318 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2275 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2319 Register elements = ToRegister(instr->elements());
2320 Register key = ToRegister(instr->key());
2321 Register result = ToRegister(instr->result()); 2276 Register result = ToRegister(instr->result());
2322 ASSERT(result.is(elements));
2323 2277
2324 // Load the result. 2278 // Load the result.
2325 __ movq(result, FieldOperand(elements, 2279 __ movq(result,
2326 key, 2280 BuildFastArrayOperand(instr->elements(), instr->key(),
2327 times_pointer_size, 2281 JSObject::FAST_ELEMENTS,
2328 FixedArray::kHeaderSize)); 2282 FixedArray::kHeaderSize - kHeapObjectTag));
2329 2283
2330 // Check for the hole value. 2284 // Check for the hole value.
2331 if (instr->hydrogen()->RequiresHoleCheck()) { 2285 if (instr->hydrogen()->RequiresHoleCheck()) {
2332 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 2286 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2333 DeoptimizeIf(equal, instr->environment()); 2287 DeoptimizeIf(equal, instr->environment());
2334 } 2288 }
2335 } 2289 }
2336 2290
2337 2291
2338 void LCodeGen::DoLoadKeyedFastDoubleElement( 2292 void LCodeGen::DoLoadKeyedFastDoubleElement(
(...skipping 13 matching lines...) Expand all
2352 } 2306 }
2353 2307
2354 Operand double_load_operand = BuildFastArrayOperand( 2308 Operand double_load_operand = BuildFastArrayOperand(
2355 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, 2309 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
2356 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2310 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2357 __ movsd(result, double_load_operand); 2311 __ movsd(result, double_load_operand);
2358 } 2312 }
2359 2313
2360 2314
2361 Operand LCodeGen::BuildFastArrayOperand( 2315 Operand LCodeGen::BuildFastArrayOperand(
2362 LOperand* external_pointer, 2316 LOperand* elements_pointer,
2363 LOperand* key, 2317 LOperand* key,
2364 JSObject::ElementsKind elements_kind, 2318 JSObject::ElementsKind elements_kind,
2365 uint32_t offset) { 2319 uint32_t offset) {
2366 Register external_pointer_reg = ToRegister(external_pointer); 2320 Register elements_pointer_reg = ToRegister(elements_pointer);
2367 int shift_size = ElementsKindToShiftSize(elements_kind); 2321 int shift_size = ElementsKindToShiftSize(elements_kind);
2368 if (key->IsConstantOperand()) { 2322 if (key->IsConstantOperand()) {
2369 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2323 int constant_value = ToInteger32(LConstantOperand::cast(key));
2370 if (constant_value & 0xF0000000) { 2324 if (constant_value & 0xF0000000) {
2371 Abort("array index constant value too big"); 2325 Abort("array index constant value too big");
2372 } 2326 }
2373 return Operand(external_pointer_reg, 2327 return Operand(elements_pointer_reg,
2374 constant_value * (1 << shift_size) + offset); 2328 constant_value * (1 << shift_size) + offset);
2375 } else { 2329 } else {
2376 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2330 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2377 return Operand(external_pointer_reg, ToRegister(key), 2331 return Operand(elements_pointer_reg, ToRegister(key),
2378 scale_factor, offset); 2332 scale_factor, offset);
2379 } 2333 }
2380 } 2334 }
2381 2335
2382 2336
2383 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2337 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2384 LLoadKeyedSpecializedArrayElement* instr) { 2338 LLoadKeyedSpecializedArrayElement* instr) {
2385 JSObject::ElementsKind elements_kind = instr->elements_kind(); 2339 JSObject::ElementsKind elements_kind = instr->elements_kind();
2386 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 2340 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2387 instr->key(), elements_kind, 0)); 2341 instr->key(), elements_kind, 0));
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2763 __ Integer32ToSmi(input_reg, input_reg); 2717 __ Integer32ToSmi(input_reg, input_reg);
2764 __ bind(deferred->exit()); 2718 __ bind(deferred->exit());
2765 } 2719 }
2766 } 2720 }
2767 2721
2768 2722
2769 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2723 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2770 XMMRegister xmm_scratch = xmm0; 2724 XMMRegister xmm_scratch = xmm0;
2771 Register output_reg = ToRegister(instr->result()); 2725 Register output_reg = ToRegister(instr->result());
2772 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2726 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2727 Label done;
2773 2728
2774 if (CpuFeatures::IsSupported(SSE4_1)) { 2729 if (CpuFeatures::IsSupported(SSE4_1)) {
2775 CpuFeatures::Scope scope(SSE4_1); 2730 CpuFeatures::Scope scope(SSE4_1);
2776 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2731 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2777 // Deoptimize if minus zero. 2732 // Deoptimize if minus zero.
2778 __ movq(output_reg, input_reg); 2733 __ movq(output_reg, input_reg);
2779 __ subq(output_reg, Immediate(1)); 2734 __ subq(output_reg, Immediate(1));
2780 DeoptimizeIf(overflow, instr->environment()); 2735 DeoptimizeIf(overflow, instr->environment());
2781 } 2736 }
2782 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 2737 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
2783 __ cvttsd2si(output_reg, xmm_scratch); 2738 __ cvttsd2si(output_reg, xmm_scratch);
2784 __ cmpl(output_reg, Immediate(0x80000000)); 2739 __ cmpl(output_reg, Immediate(0x80000000));
2785 DeoptimizeIf(equal, instr->environment()); 2740 DeoptimizeIf(equal, instr->environment());
2786 } else { 2741 } else {
2742 // Deoptimize on negative inputs.
2787 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 2743 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2788 __ ucomisd(input_reg, xmm_scratch); 2744 __ ucomisd(input_reg, xmm_scratch);
2789 2745 DeoptimizeIf(below, instr->environment());
2790 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2746 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2791 DeoptimizeIf(below_equal, instr->environment()); 2747 // Check for negative zero.
2792 } else { 2748 Label positive_sign;
2793 DeoptimizeIf(below, instr->environment()); 2749 __ j(above, &positive_sign, Label::kNear);
2750 __ movmskpd(output_reg, input_reg);
2751 __ testq(output_reg, Immediate(1));
2752 DeoptimizeIf(not_zero, instr->environment());
2753 __ Set(output_reg, 0);
2754 __ jmp(&done);
2755 __ bind(&positive_sign);
2794 } 2756 }
2795 2757
2796 // Use truncating instruction (OK because input is positive). 2758 // Use truncating instruction (OK because input is positive).
2797 __ cvttsd2si(output_reg, input_reg); 2759 __ cvttsd2si(output_reg, input_reg);
2798 2760
2799 // Overflow is signalled with minint. 2761 // Overflow is signalled with minint.
2800 __ cmpl(output_reg, Immediate(0x80000000)); 2762 __ cmpl(output_reg, Immediate(0x80000000));
2801 DeoptimizeIf(equal, instr->environment()); 2763 DeoptimizeIf(equal, instr->environment());
2802 } 2764 }
2765 __ bind(&done);
2803 } 2766 }
2804 2767
2805 2768
2806 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2769 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2807 const XMMRegister xmm_scratch = xmm0; 2770 const XMMRegister xmm_scratch = xmm0;
2808 Register output_reg = ToRegister(instr->result()); 2771 Register output_reg = ToRegister(instr->result());
2809 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2772 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2810 2773
2811 Label done; 2774 Label done;
2812 // xmm_scratch = 0.5 2775 // xmm_scratch = 0.5
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3141 case JSObject::DICTIONARY_ELEMENTS: 3104 case JSObject::DICTIONARY_ELEMENTS:
3142 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: 3105 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
3143 UNREACHABLE(); 3106 UNREACHABLE();
3144 break; 3107 break;
3145 } 3108 }
3146 } 3109 }
3147 } 3110 }
3148 3111
3149 3112
3150 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 3113 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
3151 if (instr->length()->IsRegister()) { 3114 if (instr->index()->IsConstantOperand()) {
3152 __ cmpq(ToRegister(instr->index()), ToRegister(instr->length())); 3115 if (instr->length()->IsRegister()) {
3116 __ cmpq(ToRegister(instr->length()),
3117 Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
3118 } else {
3119 __ cmpq(ToOperand(instr->length()),
3120 Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
3121 }
3153 } else { 3122 } else {
3154 __ cmpq(ToRegister(instr->index()), ToOperand(instr->length())); 3123 if (instr->length()->IsRegister()) {
3124 __ cmpq(ToRegister(instr->length()), ToRegister(instr->index()));
3125 } else {
3126 __ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
3127 }
3155 } 3128 }
3156 DeoptimizeIf(above_equal, instr->environment()); 3129 DeoptimizeIf(below_equal, instr->environment());
3157 } 3130 }
3158 3131
3159 3132
3160 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3133 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
3161 Register value = ToRegister(instr->value()); 3134 Register value = ToRegister(instr->value());
3162 Register elements = ToRegister(instr->object()); 3135 Register elements = ToRegister(instr->object());
3163 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3136 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3164 3137
3165 // Do the store. 3138 // Do the store.
3166 if (instr->key()->IsConstantOperand()) { 3139 if (instr->key()->IsConstantOperand()) {
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 __ testb(FieldOperand(input, Map::kBitFieldOffset), 3985 __ testb(FieldOperand(input, Map::kBitFieldOffset),
4013 Immediate(1 << Map::kIsUndetectable)); 3986 Immediate(1 << Map::kIsUndetectable));
4014 final_branch_condition = zero; 3987 final_branch_condition = zero;
4015 3988
4016 } else if (type_name->Equals(heap()->boolean_symbol())) { 3989 } else if (type_name->Equals(heap()->boolean_symbol())) {
4017 __ CompareRoot(input, Heap::kTrueValueRootIndex); 3990 __ CompareRoot(input, Heap::kTrueValueRootIndex);
4018 __ j(equal, true_label); 3991 __ j(equal, true_label);
4019 __ CompareRoot(input, Heap::kFalseValueRootIndex); 3992 __ CompareRoot(input, Heap::kFalseValueRootIndex);
4020 final_branch_condition = equal; 3993 final_branch_condition = equal;
4021 3994
3995 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) {
3996 __ CompareRoot(input, Heap::kNullValueRootIndex);
3997 final_branch_condition = equal;
3998
4022 } else if (type_name->Equals(heap()->undefined_symbol())) { 3999 } else if (type_name->Equals(heap()->undefined_symbol())) {
4023 __ CompareRoot(input, Heap::kUndefinedValueRootIndex); 4000 __ CompareRoot(input, Heap::kUndefinedValueRootIndex);
4024 __ j(equal, true_label); 4001 __ j(equal, true_label);
4025 __ JumpIfSmi(input, false_label); 4002 __ JumpIfSmi(input, false_label);
4026 // Check for undetectable objects => true. 4003 // Check for undetectable objects => true.
4027 __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); 4004 __ movq(input, FieldOperand(input, HeapObject::kMapOffset));
4028 __ testb(FieldOperand(input, Map::kBitFieldOffset), 4005 __ testb(FieldOperand(input, Map::kBitFieldOffset),
4029 Immediate(1 << Map::kIsUndetectable)); 4006 Immediate(1 << Map::kIsUndetectable));
4030 final_branch_condition = not_zero; 4007 final_branch_condition = not_zero;
4031 4008
4032 } else if (type_name->Equals(heap()->function_symbol())) { 4009 } else if (type_name->Equals(heap()->function_symbol())) {
4033 __ JumpIfSmi(input, false_label); 4010 __ JumpIfSmi(input, false_label);
4034 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input); 4011 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
4035 final_branch_condition = above_equal; 4012 final_branch_condition = above_equal;
4036 4013
4037 } else if (type_name->Equals(heap()->object_symbol())) { 4014 } else if (type_name->Equals(heap()->object_symbol())) {
4038 __ JumpIfSmi(input, false_label); 4015 __ JumpIfSmi(input, false_label);
4039 __ CompareRoot(input, Heap::kNullValueRootIndex); 4016 if (!FLAG_harmony_typeof) {
4040 __ j(equal, true_label); 4017 __ CompareRoot(input, Heap::kNullValueRootIndex);
4018 __ j(equal, true_label);
4019 }
4041 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 4020 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
4042 __ j(below, false_label); 4021 __ j(below, false_label);
4043 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4022 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4044 __ j(above, false_label); 4023 __ j(above, false_label);
4045 // Check for undetectable objects => false. 4024 // Check for undetectable objects => false.
4046 __ testb(FieldOperand(input, Map::kBitFieldOffset), 4025 __ testb(FieldOperand(input, Map::kBitFieldOffset),
4047 Immediate(1 << Map::kIsUndetectable)); 4026 Immediate(1 << Map::kIsUndetectable));
4048 final_branch_condition = zero; 4027 final_branch_condition = zero;
4049 4028
4050 } else { 4029 } else {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 RegisterEnvironmentForDeoptimization(environment); 4174 RegisterEnvironmentForDeoptimization(environment);
4196 ASSERT(osr_pc_offset_ == -1); 4175 ASSERT(osr_pc_offset_ == -1);
4197 osr_pc_offset_ = masm()->pc_offset(); 4176 osr_pc_offset_ = masm()->pc_offset();
4198 } 4177 }
4199 4178
4200 #undef __ 4179 #undef __
4201 4180
4202 } } // namespace v8::internal 4181 } } // namespace v8::internal
4203 4182
4204 #endif // V8_TARGET_ARCH_X64 4183 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698