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/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
6 | 6 |
7 #include "src/compiler/linkage.h" | 7 #include "src/compiler/linkage.h" |
8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
9 #include "src/interpreter/bytecode-array-iterator.h" | 9 #include "src/interpreter/bytecode-array-iterator.h" |
10 | 10 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 // Parameter (arity + 1) is special for the outer context of the function | 116 // Parameter (arity + 1) is special for the outer context of the function |
117 const Operator* op = | 117 const Operator* op = |
118 common()->Parameter(bytecode_array()->parameter_count(), "%context"); | 118 common()->Parameter(bytecode_array()->parameter_count(), "%context"); |
119 Node* node = NewNode(op, graph()->start()); | 119 Node* node = NewNode(op, graph()->start()); |
120 function_context_.set(node); | 120 function_context_.set(node); |
121 } | 121 } |
122 return function_context_.get(); | 122 return function_context_.get(); |
123 } | 123 } |
124 | 124 |
125 | 125 |
| 126 Node* BytecodeGraphBuilder::GetFunctionClosure() { |
| 127 if (!function_closure_.is_set()) { |
| 128 const Operator* op = common()->Parameter( |
| 129 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); |
| 130 Node* node = NewNode(op, graph()->start()); |
| 131 function_closure_.set(node); |
| 132 } |
| 133 return function_closure_.get(); |
| 134 } |
| 135 |
| 136 |
| 137 Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object, |
| 138 int offset) { |
| 139 return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
| 140 jsgraph()->IntPtrConstant(offset - kHeapObjectTag), |
| 141 graph()->start(), graph()->start()); |
| 142 } |
| 143 |
| 144 |
| 145 Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() { |
| 146 if (!feedback_vector_.is_set()) { |
| 147 Node* closure = GetFunctionClosure(); |
| 148 Node* shared = BuildLoadImmutableObjectField( |
| 149 closure, JSFunction::kSharedFunctionInfoOffset); |
| 150 Node* vector = BuildLoadImmutableObjectField( |
| 151 shared, SharedFunctionInfo::kFeedbackVectorOffset); |
| 152 feedback_vector_.set(vector); |
| 153 } |
| 154 return feedback_vector_.get(); |
| 155 } |
| 156 |
| 157 |
| 158 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
| 159 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); |
| 160 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); |
| 161 return VectorSlotPair(feedback_vector, slot); |
| 162 } |
| 163 |
| 164 |
| 165 void BytecodeGraphBuilder::AddEmptyFrameStateInputs(Node* node) { |
| 166 int frame_state_count = |
| 167 OperatorProperties::GetFrameStateInputCount(node->op()); |
| 168 for (int i = 0; i < frame_state_count; i++) { |
| 169 NodeProperties::ReplaceFrameStateInput(node, i, |
| 170 jsgraph()->EmptyFrameState()); |
| 171 } |
| 172 } |
| 173 |
| 174 |
126 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { | 175 bool BytecodeGraphBuilder::CreateGraph(bool stack_check) { |
127 // Set up the basic structure of the graph. Outputs for {Start} are | 176 // Set up the basic structure of the graph. Outputs for {Start} are |
128 // the formal parameters (including the receiver) plus context and | 177 // the formal parameters (including the receiver) plus context and |
129 // closure. | 178 // closure. |
130 | 179 |
131 // The additional count items are for the context and closure. | 180 // The additional count items are for the context and closure. |
132 int actual_parameter_count = bytecode_array()->parameter_count() + 2; | 181 int actual_parameter_count = bytecode_array()->parameter_count() + 2; |
133 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 182 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
134 | 183 |
135 Environment env(this, bytecode_array()->register_count(), | 184 Environment env(this, bytecode_array()->register_count(), |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 UNIMPLEMENTED(); | 357 UNIMPLEMENTED(); |
309 } | 358 } |
310 | 359 |
311 | 360 |
312 void BytecodeGraphBuilder::VisitStaContextSlot( | 361 void BytecodeGraphBuilder::VisitStaContextSlot( |
313 const interpreter::BytecodeArrayIterator& iterator) { | 362 const interpreter::BytecodeArrayIterator& iterator) { |
314 UNIMPLEMENTED(); | 363 UNIMPLEMENTED(); |
315 } | 364 } |
316 | 365 |
317 | 366 |
| 367 void BytecodeGraphBuilder::BuildNamedLoad( |
| 368 const interpreter::BytecodeArrayIterator& iterator) { |
| 369 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 370 Handle<Name> name = |
| 371 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); |
| 372 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); |
| 373 |
| 374 const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback); |
| 375 Node* node = NewNode(op, object, BuildLoadFeedbackVector()); |
| 376 // TODO(mythria): Replace with real frame state. Also add before and after |
| 377 // frame states if required. |
| 378 AddEmptyFrameStateInputs(node); |
| 379 environment()->BindAccumulator(node); |
| 380 } |
| 381 |
| 382 |
318 void BytecodeGraphBuilder::VisitLoadICSloppy( | 383 void BytecodeGraphBuilder::VisitLoadICSloppy( |
319 const interpreter::BytecodeArrayIterator& iterator) { | 384 const interpreter::BytecodeArrayIterator& iterator) { |
320 UNIMPLEMENTED(); | 385 DCHECK(is_sloppy(language_mode())); |
| 386 BuildNamedLoad(iterator); |
321 } | 387 } |
322 | 388 |
323 | 389 |
324 void BytecodeGraphBuilder::VisitLoadICStrict( | 390 void BytecodeGraphBuilder::VisitLoadICStrict( |
325 const interpreter::BytecodeArrayIterator& iterator) { | 391 const interpreter::BytecodeArrayIterator& iterator) { |
326 UNIMPLEMENTED(); | 392 DCHECK(is_strict(language_mode())); |
| 393 BuildNamedLoad(iterator); |
327 } | 394 } |
328 | 395 |
329 | 396 |
330 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy( | 397 void BytecodeGraphBuilder::VisitKeyedLoadICSloppy( |
331 const interpreter::BytecodeArrayIterator& iterator) { | 398 const interpreter::BytecodeArrayIterator& iterator) { |
332 UNIMPLEMENTED(); | 399 UNIMPLEMENTED(); |
333 } | 400 } |
334 | 401 |
335 | 402 |
336 void BytecodeGraphBuilder::VisitKeyedLoadICStrict( | 403 void BytecodeGraphBuilder::VisitKeyedLoadICStrict( |
337 const interpreter::BytecodeArrayIterator& iterator) { | 404 const interpreter::BytecodeArrayIterator& iterator) { |
338 UNIMPLEMENTED(); | 405 UNIMPLEMENTED(); |
339 } | 406 } |
340 | 407 |
341 | 408 |
342 void BytecodeGraphBuilder::VisitLoadICSloppyWide( | 409 void BytecodeGraphBuilder::VisitLoadICSloppyWide( |
343 const interpreter::BytecodeArrayIterator& iterator) { | 410 const interpreter::BytecodeArrayIterator& iterator) { |
344 UNIMPLEMENTED(); | 411 DCHECK(is_sloppy(language_mode())); |
| 412 BuildNamedLoad(iterator); |
345 } | 413 } |
346 | 414 |
347 | 415 |
348 void BytecodeGraphBuilder::VisitLoadICStrictWide( | 416 void BytecodeGraphBuilder::VisitLoadICStrictWide( |
349 const interpreter::BytecodeArrayIterator& iterator) { | 417 const interpreter::BytecodeArrayIterator& iterator) { |
350 UNIMPLEMENTED(); | 418 DCHECK(is_strict(language_mode())); |
| 419 BuildNamedLoad(iterator); |
351 } | 420 } |
352 | 421 |
353 | 422 |
354 void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide( | 423 void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide( |
355 const interpreter::BytecodeArrayIterator& iterator) { | 424 const interpreter::BytecodeArrayIterator& iterator) { |
356 UNIMPLEMENTED(); | 425 UNIMPLEMENTED(); |
357 } | 426 } |
358 | 427 |
359 | 428 |
360 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide( | 429 void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide( |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 552 } |
484 | 553 |
485 | 554 |
486 void BytecodeGraphBuilder::BuildBinaryOp( | 555 void BytecodeGraphBuilder::BuildBinaryOp( |
487 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { | 556 const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) { |
488 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 557 Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
489 Node* right = environment()->LookupAccumulator(); | 558 Node* right = environment()->LookupAccumulator(); |
490 Node* node = NewNode(js_op, left, right); | 559 Node* node = NewNode(js_op, left, right); |
491 | 560 |
492 // TODO(oth): Real frame state and environment check pointing. | 561 // TODO(oth): Real frame state and environment check pointing. |
493 int frame_state_count = | 562 AddEmptyFrameStateInputs(node); |
494 OperatorProperties::GetFrameStateInputCount(node->op()); | |
495 for (int i = 0; i < frame_state_count; i++) { | |
496 NodeProperties::ReplaceFrameStateInput(node, i, | |
497 jsgraph()->EmptyFrameState()); | |
498 } | |
499 environment()->BindAccumulator(node); | 563 environment()->BindAccumulator(node); |
500 } | 564 } |
501 | 565 |
502 | 566 |
503 void BytecodeGraphBuilder::VisitAdd( | 567 void BytecodeGraphBuilder::VisitAdd( |
504 const interpreter::BytecodeArrayIterator& iterator) { | 568 const interpreter::BytecodeArrayIterator& iterator) { |
505 BuildBinaryOp(javascript()->Add(language_mode()), iterator); | 569 BuildBinaryOp(javascript()->Add(language_mode()), iterator); |
506 } | 570 } |
507 | 571 |
508 | 572 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 | 956 |
893 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { | 957 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { |
894 if (environment()->IsMarkedAsUnreachable()) return; | 958 if (environment()->IsMarkedAsUnreachable()) return; |
895 environment()->MarkAsUnreachable(); | 959 environment()->MarkAsUnreachable(); |
896 exit_controls_.push_back(exit); | 960 exit_controls_.push_back(exit); |
897 } | 961 } |
898 | 962 |
899 } // namespace compiler | 963 } // namespace compiler |
900 } // namespace internal | 964 } // namespace internal |
901 } // namespace v8 | 965 } // namespace v8 |
OLD | NEW |