Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_optimizer.cc (revision 18171) |
| +++ runtime/vm/flow_graph_optimizer.cc (working copy) |
| @@ -784,7 +784,11 @@ |
| Value* index = NULL; |
| intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| Definition* array_op = |
| - new LoadIndexedInstr(array, index, array_cid, deopt_id); |
| + new LoadIndexedInstr(array, |
| + index, |
| + FlowGraphCompiler::ElementSizeFor(array_cid), |
| + array_cid, |
| + deopt_id); |
| call->ReplaceWith(array_op, current_iterator()); |
| RemovePushArguments(call); |
| return true; |
| @@ -1329,7 +1333,11 @@ |
| call->env(), |
| Definition::kEffect); |
| } |
| - return new LoadIndexedInstr(str, index, cid, Isolate::kNoDeoptId); |
| + return new LoadIndexedInstr(str, |
| + index, |
| + FlowGraphCompiler::ElementSizeFor(cid), |
| + cid, |
| + Isolate::kNoDeoptId); // Can't deoptimize. |
| } |
| @@ -1349,6 +1357,24 @@ |
| } |
| +static bool IsSupportedByteArrayCid(intptr_t cid) { |
| + switch (cid) { |
| + case kInt8ArrayCid: |
| + case kUint8ArrayCid: |
| + case kUint8ClampedArrayCid: |
| + case kInt16ArrayCid: |
| + case kUint16ArrayCid: |
| + case kInt32ArrayCid: |
| + case kUint32ArrayCid: |
| + case kFloat32ArrayCid: |
| + case kFloat64ArrayCid: |
|
srdjan
2013/02/06 17:11:16
They may be ordered, i.e., you could check for ran
Florian Schneider
2013/02/14 12:20:51
How can I make sure that they are ordered? It woul
srdjan
2013/02/14 16:36:35
They are ordered but not as we need it, see RawObj
|
| + return true; |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| + |
| // Inline only simple, frequently called core library methods. |
| bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| ASSERT(call->HasICData()); |
| @@ -1440,10 +1466,97 @@ |
| } |
| } |
| + if (IsSupportedByteArrayCid(class_ids[0]) && ic_data.NumberOfChecks() == 1) { |
|
srdjan
2013/02/06 17:11:16
Add Parenthesis
Florian Schneider
2013/02/14 12:20:51
Done.
|
| + Definition* array_op = NULL; |
| + switch (recognized_kind) { |
| + case MethodRecognizer::kByteArrayBaseGetInt8: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt8ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetUint8: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint8ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetInt16: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt16ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetUint16: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint16ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetInt32: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt32ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetUint32: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint32ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetFloat32: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat32ArrayCid); |
| + break; |
| + case MethodRecognizer::kByteArrayBaseGetFloat64: |
| + array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat64ArrayCid); |
| + break; |
| + default: |
| + // Unsupported method. |
| + return false; |
| + } |
| + ASSERT(array_op != NULL); |
| + call->ReplaceWith(array_op, current_iterator()); |
| + RemovePushArguments(call); |
| + return true; |
| + } |
| return false; |
| } |
| +LoadIndexedInstr* FlowGraphOptimizer::BuildByteArrayViewLoad( |
| + InstanceCallInstr* call, |
| + intptr_t receiver_cid, |
| + intptr_t view_cid) { |
| + Value* array = call->ArgumentAt(0)->value(); |
| + Value* byte_index = call->ArgumentAt(1)->value(); |
| + |
| + AddCheckClass(call, array->Copy()); |
| + const bool is_immutable = true; |
| + LoadFieldInstr* length = new LoadFieldInstr( |
| + array->Copy(), |
| + CheckArrayBoundInstr::LengthOffsetFor(receiver_cid), |
| + Type::ZoneHandle(Type::SmiType()), |
| + is_immutable); |
| + length->set_result_cid(kSmiCid); |
| + length->set_recognized_kind( |
| + LoadFieldInstr::RecognizedKindFromArrayCid(receiver_cid)); |
| + InsertBefore(call, length, NULL, Definition::kValue); |
| + |
| + // len_in_bytes = length * kBytesPerElement(receiver) |
| + intptr_t element_size = FlowGraphCompiler::ElementSizeFor(receiver_cid); |
| + ConstantInstr* bytes_per_element = |
| + new ConstantInstr(Smi::Handle(Smi::New(element_size))); |
| + InsertBefore(call, bytes_per_element, NULL, Definition::kValue); |
| + BinarySmiOpInstr* len_in_bytes = |
| + new BinarySmiOpInstr(Token::kMUL, |
| + call, |
| + new Value(length), |
| + new Value(bytes_per_element)); |
| + InsertBefore(call, len_in_bytes, call->env(), Definition::kValue); |
| + |
| + // Check byte_index < len_in_bytes. |
| + InsertBefore(call, |
| + new CheckArrayBoundInstr(new Value(len_in_bytes), |
| + byte_index->Copy(), |
| + receiver_cid, |
| + call), |
| + call->env(), |
| + Definition::kEffect); |
| + |
| + // TODO(fschneider): Optimistically build smi load for Int32 and Uint32 |
| + // loads on ia32 like we do for normal array loads, and only revert to |
| + // mint case after deoptimizing here. |
| + return new LoadIndexedInstr(array, |
| + byte_index, |
| + 1, // Index scale. |
| + view_cid, |
| + Isolate::kNoDeoptId); // Can't deoptimize. |
| +} |
| + |
| + |
| // Returns a Boolean constant if all classes in ic_data yield the same type-test |
| // result and the type tests do not depend on type arguments. Otherwise return |
| // Bool::null(). |