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

Side by Side Diff: src/compiler/js-type-feedback.cc

Issue 1135243002: [turbofan] Correctify FrameState before operations in JSTypeFeedbackSpecializer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « src/compiler/js-type-feedback.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "src/compiler.h" 11 #include "src/compiler.h"
12 #include "src/type-info.h" 12 #include "src/type-info.h"
13 13
14 #include "src/compiler/access-builder.h" 14 #include "src/compiler/access-builder.h"
15 #include "src/compiler/common-operator.h" 15 #include "src/compiler/common-operator.h"
16 #include "src/compiler/frame-states.h"
16 #include "src/compiler/node-aux-data.h" 17 #include "src/compiler/node-aux-data.h"
17 #include "src/compiler/node-matchers.h" 18 #include "src/compiler/node-matchers.h"
18 #include "src/compiler/operator-properties.h" 19 #include "src/compiler/operator-properties.h"
19 #include "src/compiler/simplified-operator.h" 20 #include "src/compiler/simplified-operator.h"
20 21
21 namespace v8 { 22 namespace v8 {
22 namespace internal { 23 namespace internal {
23 namespace compiler { 24 namespace compiler {
24 25
25 enum LoadOrStore { LOAD, STORE }; 26 enum LoadOrStore { LOAD, STORE };
26 27
27 #define EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT false
28
29 JSTypeFeedbackTable::JSTypeFeedbackTable(Zone* zone) 28 JSTypeFeedbackTable::JSTypeFeedbackTable(Zone* zone)
30 : map_(TypeFeedbackIdMap::key_compare(), 29 : map_(TypeFeedbackIdMap::key_compare(),
31 TypeFeedbackIdMap::allocator_type(zone)) {} 30 TypeFeedbackIdMap::allocator_type(zone)) {}
32 31
33 32
34 void JSTypeFeedbackTable::Record(Node* node, TypeFeedbackId id) { 33 void JSTypeFeedbackTable::Record(Node* node, TypeFeedbackId id) {
35 map_.insert(std::make_pair(node->id(), id)); 34 map_.insert(std::make_pair(node->id(), id));
36 } 35 }
37 36
38 37
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 155
157 156
158 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) { 157 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
159 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed); 158 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed);
160 Node* receiver = node->InputAt(0); 159 Node* receiver = node->InputAt(0);
161 if (IsGlobalObject(receiver)) { 160 if (IsGlobalObject(receiver)) {
162 return ReduceJSLoadNamedForGlobalVariable(node); 161 return ReduceJSLoadNamedForGlobalVariable(node);
163 } 162 }
164 163
165 if (!FLAG_turbo_deoptimization) return NoChange(); 164 if (!FLAG_turbo_deoptimization) return NoChange();
166 // TODO(titzer): deopt locations are wrong for property accesses 165 Node* frame_state_before = GetFrameStateBefore(node);
167 if (!EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT) return NoChange(); 166 if (frame_state_before == nullptr) return NoChange();
168 167
169 // TODO(turbofan): handle vector-based type feedback. 168 // TODO(turbofan): handle vector-based type feedback.
170 TypeFeedbackId id = js_type_feedback_->find(node); 169 TypeFeedbackId id = js_type_feedback_->find(node);
171 if (id.IsNone() || oracle()->LoadInlineCacheState(id) == UNINITIALIZED) { 170 if (id.IsNone() || oracle()->LoadInlineCacheState(id) == UNINITIALIZED) {
172 return NoChange(); 171 return NoChange();
173 } 172 }
174 173
175 const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); 174 const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
176 SmallMapList maps; 175 SmallMapList maps;
177 Handle<Name> name = p.name().handle(); 176 Handle<Name> name = p.name().handle();
(...skipping 12 matching lines...) Expand all
190 Node* check_success; 189 Node* check_success;
191 Node* check_failed; 190 Node* check_failed;
192 BuildMapCheck(receiver, map, true, effect, control, &check_success, 191 BuildMapCheck(receiver, map, true, effect, control, &check_success,
193 &check_failed); 192 &check_failed);
194 193
195 // Build the actual load. 194 // Build the actual load.
196 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver, 195 Node* load = graph()->NewNode(simplified()->LoadField(field_access), receiver,
197 effect, check_success); 196 effect, check_success);
198 197
199 // TODO(turbofan): handle slow case instead of deoptimizing. 198 // TODO(turbofan): handle slow case instead of deoptimizing.
200 // TODO(titzer): frame state should be from before the load. 199 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before,
201 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); 200 effect, check_failed);
202 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state, effect,
203 check_failed);
204 NodeProperties::MergeControlToEnd(graph(), common(), deopt); 201 NodeProperties::MergeControlToEnd(graph(), common(), deopt);
205 NodeProperties::ReplaceWithValue(node, load, load, check_success); 202 NodeProperties::ReplaceWithValue(node, load, load, check_success);
206 return Replace(load); 203 return Replace(load);
207 } 204 }
208 205
209 206
210 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamedForGlobalVariable( 207 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamedForGlobalVariable(
211 Node* node) { 208 Node* node) {
212 Handle<String> name = 209 Handle<String> name =
213 Handle<String>::cast(LoadNamedParametersOf(node->op()).name().handle()); 210 Handle<String>::cast(LoadNamedParametersOf(node->op()).name().handle());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 272 }
276 273
277 274
278 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadProperty(Node* node) { 275 Reduction JSTypeFeedbackSpecializer::ReduceJSLoadProperty(Node* node) {
279 return NoChange(); 276 return NoChange();
280 } 277 }
281 278
282 279
283 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) { 280 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) {
284 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed); 281 DCHECK(node->opcode() == IrOpcode::kJSStoreNamed);
285 // TODO(titzer): deopt locations are wrong for property accesses 282 Node* frame_state_before = GetFrameStateBefore(node);
286 if (!EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT) return NoChange(); 283 if (frame_state_before == nullptr) return NoChange();
287 284
288 TypeFeedbackId id = js_type_feedback_->find(node); 285 TypeFeedbackId id = js_type_feedback_->find(node);
289 if (id.IsNone() || oracle()->StoreIsUninitialized(id)) return NoChange(); 286 if (id.IsNone() || oracle()->StoreIsUninitialized(id)) return NoChange();
290 287
291 const StoreNamedParameters& p = StoreNamedParametersOf(node->op()); 288 const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
292 SmallMapList maps; 289 SmallMapList maps;
293 Handle<Name> name = p.name().handle(); 290 Handle<Name> name = p.name().handle();
294 Node* receiver = node->InputAt(0); 291 Node* receiver = node->InputAt(0);
295 Node* effect = NodeProperties::GetEffectInput(node); 292 Node* effect = NodeProperties::GetEffectInput(node);
296 GatherReceiverTypes(receiver, effect, id, name, &maps); 293 GatherReceiverTypes(receiver, effect, id, name, &maps);
(...skipping 11 matching lines...) Expand all
308 Node* check_failed; 305 Node* check_failed;
309 BuildMapCheck(receiver, map, true, effect, control, &check_success, 306 BuildMapCheck(receiver, map, true, effect, control, &check_success,
310 &check_failed); 307 &check_failed);
311 308
312 // Build the actual load. 309 // Build the actual load.
313 Node* value = node->InputAt(1); 310 Node* value = node->InputAt(1);
314 Node* store = graph()->NewNode(simplified()->StoreField(field_access), 311 Node* store = graph()->NewNode(simplified()->StoreField(field_access),
315 receiver, value, effect, check_success); 312 receiver, value, effect, check_success);
316 313
317 // TODO(turbofan): handle slow case instead of deoptimizing. 314 // TODO(turbofan): handle slow case instead of deoptimizing.
318 // TODO(titzer): frame state should be from before the store. 315 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before,
319 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); 316 effect, check_failed);
320 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state, effect,
321 check_failed);
322 NodeProperties::MergeControlToEnd(graph(), common(), deopt); 317 NodeProperties::MergeControlToEnd(graph(), common(), deopt);
323 NodeProperties::ReplaceWithValue(node, store, store, check_success); 318 NodeProperties::ReplaceWithValue(node, store, store, check_success);
324 return Replace(store); 319 return Replace(store);
325 } 320 }
326 321
327 322
328 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreProperty(Node* node) { 323 Reduction JSTypeFeedbackSpecializer::ReduceJSStoreProperty(Node* node) {
329 return NoChange(); 324 return NoChange();
330 } 325 }
331 326
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 TypeFeedbackId id, 360 TypeFeedbackId id,
366 Handle<Name> name, 361 Handle<Name> name,
367 SmallMapList* maps) { 362 SmallMapList* maps) {
368 // TODO(turbofan): filter maps by initial receiver map if known 363 // TODO(turbofan): filter maps by initial receiver map if known
369 // TODO(turbofan): filter maps by native context (if specializing) 364 // TODO(turbofan): filter maps by native context (if specializing)
370 // TODO(turbofan): filter maps by effect chain 365 // TODO(turbofan): filter maps by effect chain
371 oracle()->PropertyReceiverTypes(id, name, maps); 366 oracle()->PropertyReceiverTypes(id, name, maps);
372 } 367 }
373 368
374 369
370 // Get the frame state before an operation if it exists and has a valid
371 // bailout id.
372 Node* JSTypeFeedbackSpecializer::GetFrameStateBefore(Node* node) {
373 int count = OperatorProperties::GetFrameStateInputCount(node->op());
374 DCHECK_LE(count, 2);
375 if (count == 2) {
376 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
377 if (frame_state->opcode() == IrOpcode::kFrameState) {
378 BailoutId id = OpParameter<FrameStateCallInfo>(node).bailout_id();
379 if (id != BailoutId::None()) return frame_state;
380 }
381 }
382 return nullptr;
383 }
384
375 } // namespace compiler 385 } // namespace compiler
376 } // namespace internal 386 } // namespace internal
377 } // namespace v8 387 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-type-feedback.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698