OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 } | 710 } |
711 | 711 |
712 | 712 |
713 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 713 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
714 return AssignEnvironment(new(zone()) LDeoptimize); | 714 return AssignEnvironment(new(zone()) LDeoptimize); |
715 } | 715 } |
716 | 716 |
717 | 717 |
718 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 718 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
719 HBitwiseBinaryOperation* instr) { | 719 HBitwiseBinaryOperation* instr) { |
720 if (instr->representation().IsTagged()) { | 720 if (instr->representation().IsSmiOrTagged()) { |
721 ASSERT(instr->left()->representation().IsTagged()); | 721 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
722 ASSERT(instr->right()->representation().IsTagged()); | 722 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
723 | 723 |
724 LOperand* left = UseFixed(instr->left(), rdx); | 724 LOperand* left = UseFixed(instr->left(), rdx); |
725 LOperand* right = UseFixed(instr->right(), rax); | 725 LOperand* right = UseFixed(instr->right(), rax); |
726 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); | 726 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
727 return MarkAsCall(DefineFixed(result, rax), instr); | 727 return MarkAsCall(DefineFixed(result, rax), instr); |
728 } | 728 } |
729 | 729 |
730 ASSERT(instr->representation().IsSmiOrInteger32()); | 730 ASSERT(instr->representation().IsInteger32()); |
731 ASSERT(instr->left()->representation().Equals(instr->representation())); | 731 ASSERT(instr->left()->representation().IsInteger32()); |
732 ASSERT(instr->right()->representation().Equals(instr->representation())); | 732 ASSERT(instr->right()->representation().IsInteger32()); |
733 LOperand* left = UseRegisterAtStart(instr->left()); | 733 LOperand* left = UseRegisterAtStart(instr->left()); |
734 | 734 |
735 HValue* right_value = instr->right(); | 735 HValue* right_value = instr->right(); |
736 LOperand* right = NULL; | 736 LOperand* right = NULL; |
737 int constant_value = 0; | 737 int constant_value = 0; |
738 if (right_value->IsConstant()) { | 738 if (right_value->IsConstant()) { |
739 HConstant* constant = HConstant::cast(right_value); | 739 HConstant* constant = HConstant::cast(right_value); |
740 right = chunk_->DefineConstantOperand(constant); | 740 right = chunk_->DefineConstantOperand(constant); |
741 constant_value = constant->Integer32Value() & 0x1f; | 741 constant_value = constant->Integer32Value() & 0x1f; |
742 } else { | 742 } else { |
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 ASSERT(instr->representation().IsTagged()); | 1555 ASSERT(instr->representation().IsTagged()); |
1556 return DoArithmeticT(Token::ADD, instr); | 1556 return DoArithmeticT(Token::ADD, instr); |
1557 } | 1557 } |
1558 return NULL; | 1558 return NULL; |
1559 } | 1559 } |
1560 | 1560 |
1561 | 1561 |
1562 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1562 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1563 LOperand* left = NULL; | 1563 LOperand* left = NULL; |
1564 LOperand* right = NULL; | 1564 LOperand* right = NULL; |
1565 if (instr->representation().IsSmiOrInteger32()) { | 1565 if (instr->representation().IsInteger32()) { |
1566 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1566 ASSERT(instr->left()->representation().IsInteger32()); |
1567 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1567 ASSERT(instr->right()->representation().IsInteger32()); |
1568 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1568 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1569 right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1569 right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1570 } else { | 1570 } else { |
1571 ASSERT(instr->representation().IsDouble()); | 1571 ASSERT(instr->representation().IsDouble()); |
1572 ASSERT(instr->left()->representation().IsDouble()); | 1572 ASSERT(instr->left()->representation().IsDouble()); |
1573 ASSERT(instr->right()->representation().IsDouble()); | 1573 ASSERT(instr->right()->representation().IsDouble()); |
1574 left = UseRegisterAtStart(instr->left()); | 1574 left = UseRegisterAtStart(instr->left()); |
1575 right = UseRegisterAtStart(instr->right()); | 1575 right = UseRegisterAtStart(instr->right()); |
1576 } | 1576 } |
1577 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); | 1577 LMathMinMax* minmax = new(zone()) LMathMinMax(left, right); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 | 1990 |
1991 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1991 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1992 Representation r = instr->representation(); | 1992 Representation r = instr->representation(); |
1993 if (r.IsSmi()) { | 1993 if (r.IsSmi()) { |
1994 return DefineAsRegister(new(zone()) LConstantS); | 1994 return DefineAsRegister(new(zone()) LConstantS); |
1995 } else if (r.IsInteger32()) { | 1995 } else if (r.IsInteger32()) { |
1996 return DefineAsRegister(new(zone()) LConstantI); | 1996 return DefineAsRegister(new(zone()) LConstantI); |
1997 } else if (r.IsDouble()) { | 1997 } else if (r.IsDouble()) { |
1998 LOperand* temp = TempRegister(); | 1998 LOperand* temp = TempRegister(); |
1999 return DefineAsRegister(new(zone()) LConstantD(temp)); | 1999 return DefineAsRegister(new(zone()) LConstantD(temp)); |
2000 } else if (r.IsExternal()) { | |
2001 return DefineAsRegister(new(zone()) LConstantE); | |
2002 } else if (r.IsTagged()) { | 2000 } else if (r.IsTagged()) { |
2003 return DefineAsRegister(new(zone()) LConstantT); | 2001 return DefineAsRegister(new(zone()) LConstantT); |
2004 } else { | 2002 } else { |
2005 UNREACHABLE(); | 2003 UNREACHABLE(); |
2006 return NULL; | 2004 return NULL; |
2007 } | 2005 } |
2008 } | 2006 } |
2009 | 2007 |
2010 | 2008 |
2011 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { | 2009 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 context = UseRegister(instr->context()); | 2067 context = UseRegister(instr->context()); |
2070 value = UseRegister(instr->value()); | 2068 value = UseRegister(instr->value()); |
2071 temp = NULL; | 2069 temp = NULL; |
2072 } | 2070 } |
2073 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); | 2071 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); |
2074 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; | 2072 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
2075 } | 2073 } |
2076 | 2074 |
2077 | 2075 |
2078 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 2076 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
2079 if (instr->access().IsExternalMemory() && instr->access().offset() == 0) { | |
2080 LOperand* obj = UseRegisterOrConstantAtStart(instr->object()); | |
2081 return DefineFixed(new(zone()) LLoadNamedField(obj), rax); | |
2082 } | |
2083 LOperand* obj = UseRegisterAtStart(instr->object()); | 2077 LOperand* obj = UseRegisterAtStart(instr->object()); |
2084 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); | 2078 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); |
2085 } | 2079 } |
2086 | 2080 |
2087 | 2081 |
2088 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( | 2082 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( |
2089 HLoadNamedFieldPolymorphic* instr) { | 2083 HLoadNamedFieldPolymorphic* instr) { |
2090 ASSERT(instr->representation().IsTagged()); | 2084 ASSERT(instr->representation().IsTagged()); |
2091 if (instr->need_generic()) { | 2085 if (instr->need_generic()) { |
2092 LOperand* obj = UseFixed(instr->object(), rax); | 2086 LOperand* obj = UseFixed(instr->object(), rax); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2222 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
2229 HTransitionElementsKind* instr) { | 2223 HTransitionElementsKind* instr) { |
2230 LOperand* object = UseRegister(instr->object()); | 2224 LOperand* object = UseRegister(instr->object()); |
2231 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2225 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
2232 LOperand* object = UseRegister(instr->object()); | 2226 LOperand* object = UseRegister(instr->object()); |
2233 LOperand* new_map_reg = TempRegister(); | 2227 LOperand* new_map_reg = TempRegister(); |
2234 LOperand* temp_reg = TempRegister(); | 2228 LOperand* temp_reg = TempRegister(); |
2235 LTransitionElementsKind* result = | 2229 LTransitionElementsKind* result = |
2236 new(zone()) LTransitionElementsKind(object, new_map_reg, temp_reg); | 2230 new(zone()) LTransitionElementsKind(object, new_map_reg, temp_reg); |
2237 return result; | 2231 return result; |
2238 } else { | 2232 } else if (FLAG_compiled_transitions) { |
2239 LTransitionElementsKind* result = | 2233 LTransitionElementsKind* result = |
2240 new(zone()) LTransitionElementsKind(object, NULL, NULL); | 2234 new(zone()) LTransitionElementsKind(object, NULL, NULL); |
2241 return AssignPointerMap(result); | 2235 return AssignPointerMap(result); |
| 2236 } else { |
| 2237 LOperand* object = UseFixed(instr->object(), rax); |
| 2238 LOperand* fixed_object_reg = FixedTemp(rdx); |
| 2239 LOperand* new_map_reg = FixedTemp(rbx); |
| 2240 LTransitionElementsKind* result = |
| 2241 new(zone()) LTransitionElementsKind(object, |
| 2242 new_map_reg, |
| 2243 fixed_object_reg); |
| 2244 return MarkAsCall(result, instr); |
2242 } | 2245 } |
2243 } | 2246 } |
2244 | 2247 |
2245 | 2248 |
2246 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2249 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
2247 HTrapAllocationMemento* instr) { | 2250 HTrapAllocationMemento* instr) { |
2248 LOperand* object = UseRegister(instr->object()); | 2251 LOperand* object = UseRegister(instr->object()); |
2249 LOperand* temp = TempRegister(); | 2252 LOperand* temp = TempRegister(); |
2250 LTrapAllocationMemento* result = | 2253 LTrapAllocationMemento* result = |
2251 new(zone()) LTrapAllocationMemento(object, temp); | 2254 new(zone()) LTrapAllocationMemento(object, temp); |
2252 return AssignEnvironment(result); | 2255 return AssignEnvironment(result); |
2253 } | 2256 } |
2254 | 2257 |
2255 | 2258 |
2256 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 2259 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
2257 bool is_in_object = instr->access().IsInobject(); | 2260 bool is_in_object = instr->access().IsInobject(); |
2258 bool is_external_location = instr->access().IsExternalMemory() && | |
2259 instr->access().offset() == 0; | |
2260 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2261 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
2261 bool needs_write_barrier_for_map = !instr->transition().is_null() && | 2262 bool needs_write_barrier_for_map = !instr->transition().is_null() && |
2262 instr->NeedsWriteBarrierForMap(); | 2263 instr->NeedsWriteBarrierForMap(); |
2263 | 2264 |
2264 LOperand* obj; | 2265 LOperand* obj; |
2265 if (needs_write_barrier) { | 2266 if (needs_write_barrier) { |
2266 obj = is_in_object | 2267 obj = is_in_object |
2267 ? UseRegister(instr->object()) | 2268 ? UseRegister(instr->object()) |
2268 : UseTempRegister(instr->object()); | 2269 : UseTempRegister(instr->object()); |
2269 } else if (is_external_location) { | |
2270 ASSERT(!is_in_object); | |
2271 ASSERT(!needs_write_barrier); | |
2272 ASSERT(!needs_write_barrier_for_map); | |
2273 obj = UseRegisterOrConstant(instr->object()); | |
2274 } else { | 2270 } else { |
2275 obj = needs_write_barrier_for_map | 2271 obj = needs_write_barrier_for_map |
2276 ? UseRegister(instr->object()) | 2272 ? UseRegister(instr->object()) |
2277 : UseRegisterAtStart(instr->object()); | 2273 : UseRegisterAtStart(instr->object()); |
2278 } | 2274 } |
2279 | 2275 |
2280 bool can_be_constant = instr->value()->IsConstant() && | 2276 bool can_be_constant = instr->value()->IsConstant() && |
2281 HConstant::cast(instr->value())->NotInNewSpace() && | 2277 HConstant::cast(instr->value())->NotInNewSpace() && |
2282 !(FLAG_track_double_fields && instr->field_representation().IsDouble()); | 2278 !(FLAG_track_double_fields && instr->field_representation().IsDouble()); |
2283 | 2279 |
2284 LOperand* val; | 2280 LOperand* val; |
2285 if (needs_write_barrier) { | 2281 if (needs_write_barrier) { |
2286 val = UseTempRegister(instr->value()); | 2282 val = UseTempRegister(instr->value()); |
2287 } else if (is_external_location) { | |
2288 val = UseFixed(instr->value(), rax); | |
2289 } else if (can_be_constant) { | 2283 } else if (can_be_constant) { |
2290 val = UseRegisterOrConstant(instr->value()); | 2284 val = UseRegisterOrConstant(instr->value()); |
2291 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { | 2285 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { |
2292 val = UseTempRegister(instr->value()); | 2286 val = UseTempRegister(instr->value()); |
2293 } else if (FLAG_track_double_fields && | 2287 } else if (FLAG_track_double_fields && |
2294 instr->field_representation().IsDouble()) { | 2288 instr->field_representation().IsDouble()) { |
2295 val = UseRegisterAtStart(instr->value()); | 2289 val = UseRegisterAtStart(instr->value()); |
2296 } else { | 2290 } else { |
2297 val = UseRegister(instr->value()); | 2291 val = UseRegister(instr->value()); |
2298 } | 2292 } |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2563 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2570 LOperand* object = UseRegister(instr->object()); | 2564 LOperand* object = UseRegister(instr->object()); |
2571 LOperand* index = UseTempRegister(instr->index()); | 2565 LOperand* index = UseTempRegister(instr->index()); |
2572 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2566 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2573 } | 2567 } |
2574 | 2568 |
2575 | 2569 |
2576 } } // namespace v8::internal | 2570 } } // namespace v8::internal |
2577 | 2571 |
2578 #endif // V8_TARGET_ARCH_X64 | 2572 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |