Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 Zone* zone = graph()->zone(); | 117 Zone* zone = graph()->zone(); |
| 118 HPhi* phi = new(zone) HPhi(HPhi::kInvalidMergedIndex, zone); | 118 HPhi* phi = new(zone) HPhi(HPhi::kInvalidMergedIndex, zone); |
| 119 for (int i = 0; i < block->predecessors()->length(); i++) { | 119 for (int i = 0; i < block->predecessors()->length(); i++) { |
| 120 phi->AddInput(incoming_value); | 120 phi->AddInput(incoming_value); |
| 121 } | 121 } |
| 122 block->AddPhi(phi); | 122 block->AddPhi(phi); |
| 123 return phi; | 123 return phi; |
| 124 } | 124 } |
| 125 | 125 |
| 126 | 126 |
| 127 // Insert a newly created value check as a replacement for map checks. | |
| 128 HValue* HEscapeAnalysisPhase::NewMapCheckAndInsert( | |
| 129 HCapturedObject* state, HCheckMaps* mapcheck) { | |
|
Toon Verwaest
2013/08/28 13:29:30
Syntax nit: each argument on a single line.
Michael Starzinger
2013/08/28 13:53:15
Done. Also for the other methods above.
| |
| 130 Zone* zone = graph()->zone(); | |
| 131 HValue* value = state->values()->first(); | |
|
Toon Verwaest
2013/08/28 13:29:30
Can we have a helper method map_value() on HCaptur
Michael Starzinger
2013/08/28 13:53:15
Done.
| |
| 132 // TODO(mstarzinger): This will narrow a map check against a set of maps | |
| 133 // down to the first element in the set. Revisit and fix this. | |
| 134 Handle<Map> map_object = mapcheck->map_set()->first(); | |
| 135 UniqueValueId map_id = mapcheck->map_unique_ids()->first(); | |
| 136 HCheckValue* check = HCheckValue::New(zone, NULL, value, map_object, map_id); | |
| 137 check->InsertBefore(mapcheck); | |
| 138 return check; | |
| 139 } | |
| 140 | |
| 141 | |
| 127 // Performs a forward data-flow analysis of all loads and stores on the | 142 // Performs a forward data-flow analysis of all loads and stores on the |
| 128 // given captured allocation. This uses a reverse post-order iteration | 143 // given captured allocation. This uses a reverse post-order iteration |
| 129 // over affected basic blocks. All non-escaping instructions are handled | 144 // over affected basic blocks. All non-escaping instructions are handled |
| 130 // and replaced during the analysis. | 145 // and replaced during the analysis. |
| 131 void HEscapeAnalysisPhase::AnalyzeDataFlow(HInstruction* allocate) { | 146 void HEscapeAnalysisPhase::AnalyzeDataFlow(HInstruction* allocate) { |
| 132 HBasicBlock* allocate_block = allocate->block(); | 147 HBasicBlock* allocate_block = allocate->block(); |
| 133 block_states_.AddBlock(NULL, graph()->blocks()->length(), zone()); | 148 block_states_.AddBlock(NULL, graph()->blocks()->length(), zone()); |
| 134 | 149 |
| 135 // Iterate all blocks starting with the allocation block, since the | 150 // Iterate all blocks starting with the allocation block, since the |
| 136 // allocation cannot dominate blocks that come before. | 151 // allocation cannot dominate blocks that come before. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 case HValue::kStoreNamedField: { | 185 case HValue::kStoreNamedField: { |
| 171 HStoreNamedField* store = HStoreNamedField::cast(instr); | 186 HStoreNamedField* store = HStoreNamedField::cast(instr); |
| 172 int index = store->access().offset() / kPointerSize; | 187 int index = store->access().offset() / kPointerSize; |
| 173 if (store->object() != allocate) continue; | 188 if (store->object() != allocate) continue; |
| 174 ASSERT(store->access().IsInobject()); | 189 ASSERT(store->access().IsInobject()); |
| 175 state = NewStateCopy(store, state); | 190 state = NewStateCopy(store, state); |
| 176 state->SetOperandAt(index, store->value()); | 191 state->SetOperandAt(index, store->value()); |
| 177 if (store->has_transition()) { | 192 if (store->has_transition()) { |
| 178 state->SetOperandAt(0, store->transition()); | 193 state->SetOperandAt(0, store->transition()); |
| 179 } | 194 } |
| 180 store->DeleteAndReplaceWith(NULL); | 195 store->DeleteAndReplaceWith(store->ActualValue()); |
| 181 if (FLAG_trace_escape_analysis) { | 196 if (FLAG_trace_escape_analysis) { |
| 182 PrintF("Replacing store #%d%s\n", instr->id(), | 197 PrintF("Replacing store #%d%s\n", instr->id(), |
| 183 store->has_transition() ? " (with transition)" : ""); | 198 store->has_transition() ? " (with transition)" : ""); |
| 184 } | 199 } |
| 185 break; | 200 break; |
| 186 } | 201 } |
| 187 case HValue::kArgumentsObject: | 202 case HValue::kArgumentsObject: |
| 188 case HValue::kCapturedObject: | 203 case HValue::kCapturedObject: |
| 189 case HValue::kSimulate: { | 204 case HValue::kSimulate: { |
| 190 for (int i = 0; i < instr->OperandCount(); i++) { | 205 for (int i = 0; i < instr->OperandCount(); i++) { |
| 191 if (instr->OperandAt(i) != allocate) continue; | 206 if (instr->OperandAt(i) != allocate) continue; |
| 192 instr->SetOperandAt(i, state); | 207 instr->SetOperandAt(i, state); |
| 193 } | 208 } |
| 194 break; | 209 break; |
| 195 } | 210 } |
| 196 case HValue::kCheckHeapObject: { | 211 case HValue::kCheckHeapObject: { |
| 197 HCheckHeapObject* check = HCheckHeapObject::cast(instr); | 212 HCheckHeapObject* check = HCheckHeapObject::cast(instr); |
| 198 if (check->value() != allocate) continue; | 213 if (check->value() != allocate) continue; |
| 199 check->DeleteAndReplaceWith(NULL); | 214 check->DeleteAndReplaceWith(check->ActualValue()); |
| 200 break; | 215 break; |
| 201 } | 216 } |
| 202 case HValue::kCheckMaps: { | 217 case HValue::kCheckMaps: { |
| 203 HCheckMaps* mapcheck = HCheckMaps::cast(instr); | 218 HCheckMaps* mapcheck = HCheckMaps::cast(instr); |
| 204 if (mapcheck->value() != allocate) continue; | 219 if (mapcheck->value() != allocate) continue; |
| 205 // TODO(mstarzinger): This approach breaks if the tracked map value | 220 NewMapCheckAndInsert(state, mapcheck); |
| 206 // is not a HConstant. Find a repro test case and fix this. | |
| 207 ASSERT(mapcheck->ActualValue() == allocate); | |
| 208 mapcheck->DeleteAndReplaceWith(mapcheck->ActualValue()); | 221 mapcheck->DeleteAndReplaceWith(mapcheck->ActualValue()); |
| 209 break; | 222 break; |
| 210 } | 223 } |
| 211 default: | 224 default: |
| 212 // Nothing to see here, move along ... | 225 // Nothing to see here, move along ... |
| 213 break; | 226 break; |
| 214 } | 227 } |
| 215 } | 228 } |
| 216 | 229 |
| 217 // Propagate the block state forward to all successor blocks. | 230 // Propagate the block state forward to all successor blocks. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 AnalyzeDataFlow(allocate); | 286 AnalyzeDataFlow(allocate); |
| 274 | 287 |
| 275 cumulative_values_ += number_of_values_; | 288 cumulative_values_ += number_of_values_; |
| 276 ASSERT(allocate->HasNoUses()); | 289 ASSERT(allocate->HasNoUses()); |
| 277 ASSERT(!allocate->IsLinked()); | 290 ASSERT(!allocate->IsLinked()); |
| 278 } | 291 } |
| 279 } | 292 } |
| 280 | 293 |
| 281 | 294 |
| 282 } } // namespace v8::internal | 295 } } // namespace v8::internal |
| OLD | NEW |