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/node-properties.h" | 5 #include "src/compiler/node-properties.h" |
6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/operator-properties.h" | 11 #include "src/compiler/operator-properties.h" |
| 12 #include "src/compiler/simplified-operator.h" |
11 #include "src/compiler/verifier.h" | 13 #include "src/compiler/verifier.h" |
12 #include "src/handles-inl.h" | 14 #include "src/handles-inl.h" |
13 #include "src/objects-inl.h" | 15 #include "src/objects-inl.h" |
14 | 16 |
15 namespace v8 { | 17 namespace v8 { |
16 namespace internal { | 18 namespace internal { |
17 namespace compiler { | 19 namespace compiler { |
18 | 20 |
19 // static | 21 // static |
20 int NodeProperties::PastValueIndex(Node* node) { | 22 int NodeProperties::PastValueIndex(Node* node) { |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 323 } |
322 if (b->opcode() == IrOpcode::kCheckHeapObject) { | 324 if (b->opcode() == IrOpcode::kCheckHeapObject) { |
323 b = GetValueInput(b, 0); | 325 b = GetValueInput(b, 0); |
324 continue; | 326 continue; |
325 } | 327 } |
326 return a == b; | 328 return a == b; |
327 } | 329 } |
328 } | 330 } |
329 | 331 |
330 // static | 332 // static |
| 333 bool NodeProperties::InferReceiverMaps(Node* receiver, Node* effect, |
| 334 ZoneHandleSet<Map>* maps_return) { |
| 335 HeapObjectMatcher m(receiver); |
| 336 if (m.HasValue()) { |
| 337 Handle<Map> receiver_map(m.Value()->map()); |
| 338 if (receiver_map->is_stable()) { |
| 339 *maps_return = ZoneHandleSet<Map>(receiver_map); |
| 340 return true; |
| 341 } |
| 342 } |
| 343 while (true) { |
| 344 switch (effect->opcode()) { |
| 345 case IrOpcode::kCheckMaps: { |
| 346 Node* const object = GetValueInput(effect, 0); |
| 347 if (IsSame(receiver, object)) { |
| 348 *maps_return = CheckMapsParametersOf(effect->op()).maps(); |
| 349 return true; |
| 350 } |
| 351 break; |
| 352 } |
| 353 case IrOpcode::kJSCreate: { |
| 354 if (IsSame(receiver, effect)) { |
| 355 HeapObjectMatcher mtarget(GetValueInput(effect, 0)); |
| 356 HeapObjectMatcher mnewtarget(GetValueInput(effect, 1)); |
| 357 if (mtarget.HasValue() && mnewtarget.HasValue()) { |
| 358 Handle<JSFunction> original_constructor = |
| 359 Handle<JSFunction>::cast(mnewtarget.Value()); |
| 360 if (original_constructor->has_initial_map()) { |
| 361 Handle<Map> initial_map(original_constructor->initial_map()); |
| 362 if (initial_map->constructor_or_backpointer() == |
| 363 *mtarget.Value()) { |
| 364 *maps_return = ZoneHandleSet<Map>(initial_map); |
| 365 return true; |
| 366 } |
| 367 } |
| 368 } |
| 369 // We reached the allocation of the {receiver}. |
| 370 return false; |
| 371 } |
| 372 break; |
| 373 } |
| 374 case IrOpcode::kStoreField: { |
| 375 // We only care about StoreField of maps. |
| 376 Node* const object = GetValueInput(effect, 0); |
| 377 FieldAccess const& access = FieldAccessOf(effect->op()); |
| 378 if (access.base_is_tagged == kTaggedBase && |
| 379 access.offset == HeapObject::kMapOffset) { |
| 380 if (IsSame(receiver, object)) { |
| 381 Node* const value = GetValueInput(effect, 1); |
| 382 HeapObjectMatcher m(value); |
| 383 if (m.HasValue()) { |
| 384 *maps_return = ZoneHandleSet<Map>(Handle<Map>::cast(m.Value())); |
| 385 return true; |
| 386 } |
| 387 } |
| 388 // Without alias analysis we cannot tell whether this |
| 389 // StoreField[map] affects {receiver} or not. |
| 390 return false; |
| 391 } |
| 392 break; |
| 393 } |
| 394 case IrOpcode::kJSStoreMessage: |
| 395 case IrOpcode::kJSStoreModule: |
| 396 case IrOpcode::kStoreElement: |
| 397 case IrOpcode::kStoreTypedElement: { |
| 398 // These never change the map of objects. |
| 399 break; |
| 400 } |
| 401 default: { |
| 402 DCHECK_EQ(1, effect->op()->EffectOutputCount()); |
| 403 if (effect->op()->EffectInputCount() != 1 || |
| 404 !effect->op()->HasProperty(Operator::kNoWrite)) { |
| 405 // Didn't find any appropriate CheckMaps node. |
| 406 return false; |
| 407 } |
| 408 break; |
| 409 } |
| 410 } |
| 411 DCHECK_EQ(1, effect->op()->EffectInputCount()); |
| 412 effect = NodeProperties::GetEffectInput(effect); |
| 413 } |
| 414 } |
| 415 |
| 416 // static |
331 MaybeHandle<Context> NodeProperties::GetSpecializationContext( | 417 MaybeHandle<Context> NodeProperties::GetSpecializationContext( |
332 Node* node, MaybeHandle<Context> context) { | 418 Node* node, MaybeHandle<Context> context) { |
333 switch (node->opcode()) { | 419 switch (node->opcode()) { |
334 case IrOpcode::kHeapConstant: | 420 case IrOpcode::kHeapConstant: |
335 return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node)); | 421 return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node)); |
336 case IrOpcode::kParameter: { | 422 case IrOpcode::kParameter: { |
337 Node* const start = NodeProperties::GetValueInput(node, 0); | 423 Node* const start = NodeProperties::GetValueInput(node, 0); |
338 DCHECK_EQ(IrOpcode::kStart, start->opcode()); | 424 DCHECK_EQ(IrOpcode::kStart, start->opcode()); |
339 int const index = ParameterIndexOf(node->op()); | 425 int const index = ParameterIndexOf(node->op()); |
340 // The context is always the last parameter to a JavaScript function, and | 426 // The context is always the last parameter to a JavaScript function, and |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 // static | 468 // static |
383 bool NodeProperties::IsInputRange(Edge edge, int first, int num) { | 469 bool NodeProperties::IsInputRange(Edge edge, int first, int num) { |
384 if (num == 0) return false; | 470 if (num == 0) return false; |
385 int const index = edge.index(); | 471 int const index = edge.index(); |
386 return first <= index && index < first + num; | 472 return first <= index && index < first + num; |
387 } | 473 } |
388 | 474 |
389 } // namespace compiler | 475 } // namespace compiler |
390 } // namespace internal | 476 } // namespace internal |
391 } // namespace v8 | 477 } // namespace v8 |
OLD | NEW |