| 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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 550 } | 550 } | 
| 551 | 551 | 
| 552 | 552 | 
| 553 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { | 553 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { | 
| 554   return value->IsConstant() | 554   return value->IsConstant() | 
| 555       ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 555       ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 
| 556       : UseRegisterAtStart(value); | 556       : UseRegisterAtStart(value); | 
| 557 } | 557 } | 
| 558 | 558 | 
| 559 | 559 | 
|  | 560 LOperand* LChunkBuilder::UseConstant(HValue* value) { | 
|  | 561   return chunk_->DefineConstantOperand(HConstant::cast(value)); | 
|  | 562 } | 
|  | 563 | 
|  | 564 | 
| 560 LOperand* LChunkBuilder::UseAny(HValue* value) { | 565 LOperand* LChunkBuilder::UseAny(HValue* value) { | 
| 561   return value->IsConstant() | 566   return value->IsConstant() | 
| 562       ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 567       ? chunk_->DefineConstantOperand(HConstant::cast(value)) | 
| 563       :  Use(value, new(zone()) LUnallocated(LUnallocated::ANY)); | 568       :  Use(value, new(zone()) LUnallocated(LUnallocated::ANY)); | 
| 564 } | 569 } | 
| 565 | 570 | 
| 566 | 571 | 
| 567 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 572 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 
| 568   if (value->EmitAtUses()) { | 573   if (value->EmitAtUses()) { | 
| 569     HInstruction* instr = HInstruction::cast(value); | 574     HInstruction* instr = HInstruction::cast(value); | 
| (...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2108 | 2113 | 
| 2109 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 2114 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 
| 2110   LOperand* object = UseFixed(instr->object(), rdx); | 2115   LOperand* object = UseFixed(instr->object(), rdx); | 
| 2111   LOperand* key = UseFixed(instr->key(), rax); | 2116   LOperand* key = UseFixed(instr->key(), rax); | 
| 2112 | 2117 | 
| 2113   LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(object, key); | 2118   LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(object, key); | 
| 2114   return MarkAsCall(DefineFixed(result, rax), instr); | 2119   return MarkAsCall(DefineFixed(result, rax), instr); | 
| 2115 } | 2120 } | 
| 2116 | 2121 | 
| 2117 | 2122 | 
| 2118 // DoStoreKeyed and DoStoreNamedField have special considerations for allowing |  | 
| 2119 // use of a constant instead of a register. |  | 
| 2120 static bool StoreConstantValueAllowed(HValue* value) { |  | 
| 2121   if (value->IsConstant()) { |  | 
| 2122     HConstant* constant_value = HConstant::cast(value); |  | 
| 2123     return constant_value->HasSmiValue() |  | 
| 2124         || constant_value->HasDoubleValue() |  | 
| 2125         || constant_value->ImmortalImmovable(); |  | 
| 2126   } |  | 
| 2127   return false; |  | 
| 2128 } |  | 
| 2129 |  | 
| 2130 |  | 
| 2131 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2123 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 
| 2132   ElementsKind elements_kind = instr->elements_kind(); | 2124   ElementsKind elements_kind = instr->elements_kind(); | 
| 2133   bool clobbers_key = instr->key()->representation().IsTagged(); | 2125   bool clobbers_key = instr->key()->representation().IsTagged(); | 
| 2134 | 2126 | 
| 2135   if (!instr->is_external()) { | 2127   if (!instr->is_external()) { | 
| 2136     ASSERT(instr->elements()->representation().IsTagged()); | 2128     ASSERT(instr->elements()->representation().IsTagged()); | 
| 2137     bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2129     bool needs_write_barrier = instr->NeedsWriteBarrier(); | 
| 2138     LOperand* object = NULL; | 2130     LOperand* object = NULL; | 
| 2139     LOperand* key = NULL; | 2131     LOperand* key = NULL; | 
| 2140     LOperand* val = NULL; | 2132     LOperand* val = NULL; | 
| 2141 | 2133 | 
| 2142     if (instr->value()->representation().IsDouble()) { | 2134     if (instr->value()->representation().IsDouble()) { | 
| 2143       object = UseRegisterAtStart(instr->elements()); | 2135       object = UseRegisterAtStart(instr->elements()); | 
| 2144       val = UseTempRegister(instr->value()); | 2136       val = UseTempRegister(instr->value()); | 
| 2145       key = clobbers_key ? UseTempRegister(instr->key()) | 2137       key = clobbers_key ? UseTempRegister(instr->key()) | 
| 2146           : UseRegisterOrConstantAtStart(instr->key()); | 2138           : UseRegisterOrConstantAtStart(instr->key()); | 
| 2147     } else { | 2139     } else { | 
| 2148       ASSERT(instr->value()->representation().IsTagged()); | 2140       ASSERT(instr->value()->representation().IsTagged()); | 
| 2149       object = UseTempRegister(instr->elements()); | 2141       object = UseTempRegister(instr->elements()); | 
| 2150       if (needs_write_barrier) { | 2142       if (needs_write_barrier) { | 
| 2151         val = UseTempRegister(instr->value()); | 2143         val = UseTempRegister(instr->value()); | 
| 2152         key = UseTempRegister(instr->key()); | 2144         key = UseTempRegister(instr->key()); | 
| 2153       } else { | 2145       } else { | 
| 2154         if (StoreConstantValueAllowed(instr->value())) { | 2146         val = UseRegisterOrConstantAtStart(instr->value()); | 
| 2155           val = UseRegisterOrConstantAtStart(instr->value()); |  | 
| 2156         } else { |  | 
| 2157           val = UseRegisterAtStart(instr->value()); |  | 
| 2158         } |  | 
| 2159 | 2147 | 
| 2160         if (clobbers_key) { | 2148         if (clobbers_key) { | 
| 2161           key = UseTempRegister(instr->key()); | 2149           key = UseTempRegister(instr->key()); | 
| 2162         } else if (StoreConstantValueAllowed(instr->key())) { | 2150         } else { | 
| 2163           key = UseRegisterOrConstantAtStart(instr->key()); | 2151           key = UseRegisterOrConstantAtStart(instr->key()); | 
| 2164         } else { |  | 
| 2165           key = UseRegisterAtStart(instr->key()); |  | 
| 2166         } | 2152         } | 
| 2167       } | 2153       } | 
| 2168     } | 2154     } | 
| 2169 | 2155 | 
| 2170     return new(zone()) LStoreKeyed(object, key, val); | 2156     return new(zone()) LStoreKeyed(object, key, val); | 
| 2171   } | 2157   } | 
| 2172 | 2158 | 
| 2173   ASSERT( | 2159   ASSERT( | 
| 2174       (instr->value()->representation().IsInteger32() && | 2160       (instr->value()->representation().IsInteger32() && | 
| 2175        (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 2161        (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2251   if (needs_write_barrier) { | 2237   if (needs_write_barrier) { | 
| 2252     obj = instr->is_in_object() | 2238     obj = instr->is_in_object() | 
| 2253         ? UseRegister(instr->object()) | 2239         ? UseRegister(instr->object()) | 
| 2254         : UseTempRegister(instr->object()); | 2240         : UseTempRegister(instr->object()); | 
| 2255   } else { | 2241   } else { | 
| 2256     obj = needs_write_barrier_for_map | 2242     obj = needs_write_barrier_for_map | 
| 2257         ? UseRegister(instr->object()) | 2243         ? UseRegister(instr->object()) | 
| 2258         : UseRegisterAtStart(instr->object()); | 2244         : UseRegisterAtStart(instr->object()); | 
| 2259   } | 2245   } | 
| 2260 | 2246 | 
|  | 2247   bool can_be_constant = instr->value()->IsConstant() && | 
|  | 2248       !HConstant::cast(instr->value())->InNewSpace(); | 
|  | 2249 | 
| 2261   LOperand* val; | 2250   LOperand* val; | 
| 2262   if (needs_write_barrier) { | 2251   if (needs_write_barrier) { | 
| 2263     val = UseTempRegister(instr->value()); | 2252     val = UseTempRegister(instr->value()); | 
| 2264   } else if (StoreConstantValueAllowed(instr->value())) { | 2253   } else if (can_be_constant) { | 
| 2265     val = UseRegisterOrConstant(instr->value()); | 2254     val = UseRegisterOrConstant(instr->value()); | 
| 2266   } else { | 2255   } else { | 
| 2267     val = UseRegister(instr->value()); | 2256     val = UseRegister(instr->value()); | 
| 2268   } | 2257   } | 
| 2269 | 2258 | 
| 2270   // We only need a scratch register if we have a write barrier or we | 2259   // We only need a scratch register if we have a write barrier or we | 
| 2271   // have a store into the properties array (not in-object-property). | 2260   // have a store into the properties array (not in-object-property). | 
| 2272   LOperand* temp = (!instr->is_in_object() || needs_write_barrier || | 2261   LOperand* temp = (!instr->is_in_object() || needs_write_barrier || | 
| 2273       needs_write_barrier_for_map) ? TempRegister() : NULL; | 2262       needs_write_barrier_for_map) ? TempRegister() : NULL; | 
| 2274 | 2263 | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2316 | 2305 | 
| 2317 LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) { | 2306 LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) { | 
| 2318   info()->MarkAsDeferredCalling(); | 2307   info()->MarkAsDeferredCalling(); | 
| 2319   LAllocateObject* result = new(zone()) LAllocateObject(TempRegister()); | 2308   LAllocateObject* result = new(zone()) LAllocateObject(TempRegister()); | 
| 2320   return AssignPointerMap(DefineAsRegister(result)); | 2309   return AssignPointerMap(DefineAsRegister(result)); | 
| 2321 } | 2310 } | 
| 2322 | 2311 | 
| 2323 | 2312 | 
| 2324 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 2313 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 
| 2325   info()->MarkAsDeferredCalling(); | 2314   info()->MarkAsDeferredCalling(); | 
| 2326   LOperand* size = UseTempRegister(instr->size()); | 2315   LOperand* size = instr->size()->IsConstant() | 
|  | 2316       ? UseConstant(instr->size()) | 
|  | 2317       : UseTempRegister(instr->size()); | 
| 2327   LOperand* temp = TempRegister(); | 2318   LOperand* temp = TempRegister(); | 
| 2328   LAllocate* result = new(zone()) LAllocate(size, temp); | 2319   LAllocate* result = new(zone()) LAllocate(size, temp); | 
| 2329   return AssignPointerMap(DefineAsRegister(result)); | 2320   return AssignPointerMap(DefineAsRegister(result)); | 
| 2330 } | 2321 } | 
| 2331 | 2322 | 
| 2332 | 2323 | 
| 2333 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 2324 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 
| 2334   return MarkAsCall(DefineFixed(new(zone()) LArrayLiteral, rax), instr); | 2325   return MarkAsCall(DefineFixed(new(zone()) LArrayLiteral, rax), instr); | 
| 2335 } | 2326 } | 
| 2336 | 2327 | 
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2562 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2553 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 
| 2563   LOperand* object = UseRegister(instr->object()); | 2554   LOperand* object = UseRegister(instr->object()); | 
| 2564   LOperand* index = UseTempRegister(instr->index()); | 2555   LOperand* index = UseTempRegister(instr->index()); | 
| 2565   return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2556   return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 
| 2566 } | 2557 } | 
| 2567 | 2558 | 
| 2568 | 2559 | 
| 2569 } }  // namespace v8::internal | 2560 } }  // namespace v8::internal | 
| 2570 | 2561 | 
| 2571 #endif  // V8_TARGET_ARCH_X64 | 2562 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|