| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/js-type-feedback.h" | 5 #include "src/compiler/js-type-feedback.h" |
| 6 | 6 |
| 7 #include "src/property-details.h" | 7 #include "src/property-details.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/ast.h" | 10 #include "src/ast.h" |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 } | 139 } |
| 140 | 140 |
| 141 | 141 |
| 142 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { | 142 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { |
| 143 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); | 143 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); |
| 144 if (mode() != kDeoptimizationEnabled) return NoChange(); | 144 if (mode() != kDeoptimizationEnabled) return NoChange(); |
| 145 Node* frame_state_before = GetFrameStateBefore(node); | 145 Node* frame_state_before = GetFrameStateBefore(node); |
| 146 if (frame_state_before == nullptr) return NoChange(); | 146 if (frame_state_before == nullptr) return NoChange(); |
| 147 | 147 |
| 148 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); | 148 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); |
| 149 Handle<Name> name = p.name().handle(); | |
| 150 SmallMapList maps; | 149 SmallMapList maps; |
| 151 | 150 |
| 152 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); | 151 FeedbackVectorICSlot slot = js_type_feedback_->FindFeedbackVectorICSlot(node); |
| 153 if (slot.IsInvalid() || | 152 if (slot.IsInvalid() || |
| 154 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { | 153 oracle()->LoadInlineCacheState(slot) == UNINITIALIZED) { |
| 155 // No type feedback ids or the load is uninitialized. | 154 // No type feedback ids or the load is uninitialized. |
| 156 return NoChange(); | 155 return NoChange(); |
| 157 } | 156 } |
| 158 oracle()->PropertyReceiverTypes(slot, name, &maps); | 157 oracle()->PropertyReceiverTypes(slot, p.name(), &maps); |
| 159 | 158 |
| 160 Node* receiver = node->InputAt(0); | 159 Node* receiver = node->InputAt(0); |
| 161 Node* effect = NodeProperties::GetEffectInput(node); | 160 Node* effect = NodeProperties::GetEffectInput(node); |
| 162 | 161 |
| 163 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 162 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
| 164 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); | 163 if (!ENABLE_FAST_PROPERTY_LOADS) return NoChange(); |
| 165 | 164 |
| 166 Handle<Map> map = maps.first(); | 165 Handle<Map> map = maps.first(); |
| 167 FieldAccess field_access; | 166 FieldAccess field_access; |
| 168 if (!GetInObjectFieldAccess(LOAD, map, name, &field_access)) { | 167 if (!GetInObjectFieldAccess(LOAD, map, p.name(), &field_access)) { |
| 169 return NoChange(); | 168 return NoChange(); |
| 170 } | 169 } |
| 171 | 170 |
| 172 Node* control = NodeProperties::GetControlInput(node); | 171 Node* control = NodeProperties::GetControlInput(node); |
| 173 Node* check_success; | 172 Node* check_success; |
| 174 Node* check_failed; | 173 Node* check_failed; |
| 175 BuildMapCheck(receiver, map, true, effect, control, &check_success, | 174 BuildMapCheck(receiver, map, true, effect, control, &check_success, |
| 176 &check_failed); | 175 &check_failed); |
| 177 | 176 |
| 178 // Build the actual load. | 177 // Build the actual load. |
| 179 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver, | 178 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver, |
| 180 effect, check_success); | 179 effect, check_success); |
| 181 | 180 |
| 182 // TODO(turbofan): handle slow case instead of deoptimizing. | 181 // TODO(turbofan): handle slow case instead of deoptimizing. |
| 183 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before, | 182 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before, |
| 184 effect, check_failed); | 183 effect, check_failed); |
| 185 NodeProperties::MergeControlToEnd(graph(), common(), deopt); | 184 NodeProperties::MergeControlToEnd(graph(), common(), deopt); |
| 186 ReplaceWithValue(node, load, load, check_success); | 185 ReplaceWithValue(node, load, load, check_success); |
| 187 return Replace(load); | 186 return Replace(load); |
| 188 } | 187 } |
| 189 | 188 |
| 190 | 189 |
| 191 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) { | 190 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) { |
| 192 DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal); | 191 DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal); |
| 193 Handle<String> name = | 192 Handle<String> name = |
| 194 Handle<String>::cast(LoadGlobalParametersOf(node->op()).name().handle()); | 193 Handle<String>::cast(LoadGlobalParametersOf(node->op()).name()); |
| 195 // Try to optimize loads from the global object. | 194 // Try to optimize loads from the global object. |
| 196 Handle<Object> constant_value = | 195 Handle<Object> constant_value = |
| 197 jsgraph()->isolate()->factory()->GlobalConstantFor(name); | 196 jsgraph()->isolate()->factory()->GlobalConstantFor(name); |
| 198 if (!constant_value.is_null()) { | 197 if (!constant_value.is_null()) { |
| 199 // Always optimize global constants. | 198 // Always optimize global constants. |
| 200 Node* constant = jsgraph()->Constant(constant_value); | 199 Node* constant = jsgraph()->Constant(constant_value); |
| 201 ReplaceWithValue(node, constant); | 200 ReplaceWithValue(node, constant); |
| 202 return Replace(constant); | 201 return Replace(constant); |
| 203 } | 202 } |
| 204 | 203 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 return NoChange(); | 259 return NoChange(); |
| 261 } | 260 } |
| 262 | 261 |
| 263 | 262 |
| 264 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) { | 263 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) { |
| 265 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed); | 264 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed); |
| 266 Node* frame_state_before = GetFrameStateBefore(node); | 265 Node* frame_state_before = GetFrameStateBefore(node); |
| 267 if (frame_state_before == nullptr) return NoChange(); | 266 if (frame_state_before == nullptr) return NoChange(); |
| 268 | 267 |
| 269 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); | 268 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); |
| 270 Handle<Name> name = p.name().handle(); | |
| 271 SmallMapList maps; | 269 SmallMapList maps; |
| 272 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); | 270 TypeFeedbackId id = js_type_feedback_->FindTypeFeedbackId(node); |
| 273 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { | 271 if (id.IsNone() || oracle()->StoreIsUninitialized(id) == UNINITIALIZED) { |
| 274 // No type feedback ids or the store is uninitialized. | 272 // No type feedback ids or the store is uninitialized. |
| 275 // TODO(titzer): no feedback from vector ICs from stores. | 273 // TODO(titzer): no feedback from vector ICs from stores. |
| 276 return NoChange(); | 274 return NoChange(); |
| 277 } else { | 275 } else { |
| 278 oracle()->AssignmentReceiverTypes(id, name, &maps); | 276 oracle()->AssignmentReceiverTypes(id, p.name(), &maps); |
| 279 } | 277 } |
| 280 | 278 |
| 281 Node* receiver = node->InputAt(0); | 279 Node* receiver = node->InputAt(0); |
| 282 Node* effect = NodeProperties::GetEffectInput(node); | 280 Node* effect = NodeProperties::GetEffectInput(node); |
| 283 | 281 |
| 284 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism | 282 if (maps.length() != 1) return NoChange(); // TODO(turbofan): polymorphism |
| 285 | 283 |
| 286 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); | 284 if (!ENABLE_FAST_PROPERTY_STORES) return NoChange(); |
| 287 | 285 |
| 288 Handle<Map> map = maps.first(); | 286 Handle<Map> map = maps.first(); |
| 289 FieldAccess field_access; | 287 FieldAccess field_access; |
| 290 if (!GetInObjectFieldAccess(STORE, map, name, &field_access)) { | 288 if (!GetInObjectFieldAccess(STORE, map, p.name(), &field_access)) { |
| 291 return NoChange(); | 289 return NoChange(); |
| 292 } | 290 } |
| 293 | 291 |
| 294 Node* control = NodeProperties::GetControlInput(node); | 292 Node* control = NodeProperties::GetControlInput(node); |
| 295 Node* check_success; | 293 Node* check_success; |
| 296 Node* check_failed; | 294 Node* check_failed; |
| 297 BuildMapCheck(receiver, map, true, effect, control, &check_success, | 295 BuildMapCheck(receiver, map, true, effect, control, &check_success, |
| 298 &check_failed); | 296 &check_failed); |
| 299 | 297 |
| 300 // Build the actual load. | 298 // Build the actual load. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 BailoutId id = OpParameter<FrameStateInfo>(node).bailout_id(); | 355 BailoutId id = OpParameter<FrameStateInfo>(node).bailout_id(); |
| 358 if (id != BailoutId::None()) return frame_state; | 356 if (id != BailoutId::None()) return frame_state; |
| 359 } | 357 } |
| 360 } | 358 } |
| 361 return nullptr; | 359 return nullptr; |
| 362 } | 360 } |
| 363 | 361 |
| 364 } // namespace compiler | 362 } // namespace compiler |
| 365 } // namespace internal | 363 } // namespace internal |
| 366 } // namespace v8 | 364 } // namespace v8 |
| OLD | NEW |