| Index: runtime/vm/flow_graph_compiler.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_compiler.cc (revision 17245)
|
| +++ runtime/vm/flow_graph_compiler.cc (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| @@ -157,16 +157,6 @@
|
| }
|
|
|
|
|
| -FlowGraphCompiler::~FlowGraphCompiler() {
|
| - // BlockInfos are zone-allocated, so their destructors are not called.
|
| - // Verify the labels explicitly here.
|
| - for (int i = 0; i < block_info_.length(); ++i) {
|
| - ASSERT(!block_info_[i]->label.IsLinked());
|
| - ASSERT(!block_info_[i]->label.HasNear());
|
| - }
|
| -}
|
| -
|
| -
|
| bool FlowGraphCompiler::HasFinally() const {
|
| return parsed_function().function().has_finally();
|
| }
|
| @@ -355,17 +345,17 @@
|
| // Slow path code can have registers at the safepoint.
|
| if (!locs->always_calls()) {
|
| RegisterSet* regs = locs->live_registers();
|
| - if (regs->xmm_regs_count() > 0) {
|
| - // Denote XMM registers with 0 bits in the stackmap. Based on the
|
| - // assumption that there are normally few live XMM registers, this
|
| + if (regs->fpu_regs_count() > 0) {
|
| + // Denote FPU registers with 0 bits in the stackmap. Based on the
|
| + // assumption that there are normally few live FPU registers, this
|
| // encoding is simpler and roughly as compact as storing a separate
|
| - // count of XMM registers.
|
| + // count of FPU registers.
|
| //
|
| - // XMM registers have the highest register number at the highest
|
| + // FPU registers have the highest register number at the highest
|
| // address (i.e., first in the stackmap).
|
| - for (intptr_t i = kNumberOfXmmRegisters - 1; i >= 0; --i) {
|
| - XmmRegister reg = static_cast<XmmRegister>(i);
|
| - if (regs->ContainsXmmRegister(reg)) {
|
| + for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
|
| + FpuRegister reg = static_cast<FpuRegister>(i);
|
| + if (regs->ContainsFpuRegister(reg)) {
|
| for (intptr_t j = 0;
|
| j < FlowGraphAllocator::kDoubleSpillSlotFactor;
|
| ++j) {
|
| @@ -660,115 +650,6 @@
|
| }
|
|
|
|
|
| -struct CidTarget {
|
| - intptr_t cid;
|
| - Function* target;
|
| - intptr_t count;
|
| - CidTarget(intptr_t cid_arg,
|
| - Function* target_arg,
|
| - intptr_t count_arg)
|
| - : cid(cid_arg), target(target_arg), count(count_arg) {}
|
| -};
|
| -
|
| -
|
| -// Returns 'sorted' array in decreasing count order.
|
| -// The expected number of elements to sort is less than 10.
|
| -static void SortICDataByCount(const ICData& ic_data,
|
| - GrowableArray<CidTarget>* sorted) {
|
| - ASSERT(ic_data.num_args_tested() == 1);
|
| - const intptr_t len = ic_data.NumberOfChecks();
|
| - sorted->Clear();
|
| -
|
| - for (int i = 0; i < len; i++) {
|
| - sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
|
| - &Function::ZoneHandle(ic_data.GetTargetAt(i)),
|
| - ic_data.GetCountAt(i)));
|
| - }
|
| - for (int i = 0; i < len; i++) {
|
| - intptr_t largest_ix = i;
|
| - for (int k = i + 1; k < len; k++) {
|
| - if ((*sorted)[largest_ix].count < (*sorted)[k].count) {
|
| - largest_ix = k;
|
| - }
|
| - }
|
| - if (i != largest_ix) {
|
| - // Swap.
|
| - CidTarget temp = (*sorted)[i];
|
| - (*sorted)[i] = (*sorted)[largest_ix];
|
| - (*sorted)[largest_ix] = temp;
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
|
| - Register class_id_reg,
|
| - intptr_t arg_count,
|
| - const Array& arg_names,
|
| - Label* deopt,
|
| - intptr_t deopt_id,
|
| - intptr_t token_index,
|
| - LocationSummary* locs) {
|
| - ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
|
| - Label match_found;
|
| - const intptr_t len = ic_data.NumberOfChecks();
|
| - GrowableArray<CidTarget> sorted(len);
|
| - SortICDataByCount(ic_data, &sorted);
|
| - for (intptr_t i = 0; i < len; i++) {
|
| - const bool is_last_check = (i == (len - 1));
|
| - Label next_test;
|
| - assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid));
|
| - if (is_last_check) {
|
| - assembler()->j(NOT_EQUAL, deopt);
|
| - } else {
|
| - assembler()->j(NOT_EQUAL, &next_test);
|
| - }
|
| - GenerateStaticCall(deopt_id,
|
| - token_index,
|
| - *sorted[i].target,
|
| - arg_count,
|
| - arg_names,
|
| - locs);
|
| - if (!is_last_check) {
|
| - assembler()->jmp(&match_found);
|
| - }
|
| - assembler()->Bind(&next_test);
|
| - }
|
| - assembler()->Bind(&match_found);
|
| -}
|
| -
|
| -
|
| -void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition,
|
| - XmmRegister left,
|
| - XmmRegister right,
|
| - BranchInstr* branch) {
|
| - ASSERT(branch != NULL);
|
| - assembler()->comisd(left, right);
|
| - BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
|
| - branch->true_successor() : branch->false_successor();
|
| - assembler()->j(PARITY_EVEN, GetBlockLabel(nan_result));
|
| - branch->EmitBranchOnCondition(this, true_condition);
|
| -}
|
| -
|
| -
|
| -
|
| -void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
|
| - XmmRegister left,
|
| - XmmRegister right,
|
| - Register result) {
|
| - assembler()->comisd(left, right);
|
| - Label is_false, is_true, done;
|
| - assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN false;
|
| - assembler()->j(true_condition, &is_true, Assembler::kNearJump);
|
| - assembler()->Bind(&is_false);
|
| - assembler()->LoadObject(result, Bool::False());
|
| - assembler()->jmp(&done);
|
| - assembler()->Bind(&is_true);
|
| - assembler()->LoadObject(result, Bool::True());
|
| - assembler()->Bind(&done);
|
| -}
|
| -
|
| -
|
| // Allocate a register that is not explicitly blocked.
|
| static Register AllocateFreeRegister(bool* blocked_registers) {
|
| for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
|
| @@ -873,7 +754,7 @@
|
| case Location::kSameAsFirstInput:
|
| result_location = locs->in(0);
|
| break;
|
| - case Location::kRequiresXmmRegister:
|
| + case Location::kRequiresFpuRegister:
|
| UNREACHABLE();
|
| break;
|
| }
|
| @@ -990,48 +871,6 @@
|
| }
|
|
|
|
|
| -Condition FlowGraphCompiler::FlipCondition(Condition condition) {
|
| - switch (condition) {
|
| - case EQUAL: return EQUAL;
|
| - case NOT_EQUAL: return NOT_EQUAL;
|
| - case LESS: return GREATER;
|
| - case LESS_EQUAL: return GREATER_EQUAL;
|
| - case GREATER: return LESS;
|
| - case GREATER_EQUAL: return LESS_EQUAL;
|
| - case BELOW: return ABOVE;
|
| - case BELOW_EQUAL: return ABOVE_EQUAL;
|
| - case ABOVE: return BELOW;
|
| - case ABOVE_EQUAL: return BELOW_EQUAL;
|
| - default:
|
| - UNIMPLEMENTED();
|
| - return EQUAL;
|
| - }
|
| -}
|
| -
|
| -
|
| -bool FlowGraphCompiler::EvaluateCondition(Condition condition,
|
| - intptr_t left,
|
| - intptr_t right) {
|
| - const uintptr_t unsigned_left = static_cast<uintptr_t>(left);
|
| - const uintptr_t unsigned_right = static_cast<uintptr_t>(right);
|
| - switch (condition) {
|
| - case EQUAL: return left == right;
|
| - case NOT_EQUAL: return left != right;
|
| - case LESS: return left < right;
|
| - case LESS_EQUAL: return left <= right;
|
| - case GREATER: return left > right;
|
| - case GREATER_EQUAL: return left >= right;
|
| - case BELOW: return unsigned_left < unsigned_right;
|
| - case BELOW_EQUAL: return unsigned_left <= unsigned_right;
|
| - case ABOVE: return unsigned_left > unsigned_right;
|
| - case ABOVE_EQUAL: return unsigned_left >= unsigned_right;
|
| - default:
|
| - UNIMPLEMENTED();
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -
|
| intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
|
| switch (cid) {
|
| case kArrayCid:
|
| @@ -1094,74 +933,6 @@
|
| }
|
|
|
|
|
| -FieldAddress FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
|
| - Register array,
|
| - intptr_t index) {
|
| - const int64_t disp =
|
| - static_cast<int64_t>(index) * ElementSizeFor(cid) + DataOffsetFor(cid);
|
| - ASSERT(Utils::IsInt(32, disp));
|
| - return FieldAddress(array, static_cast<int32_t>(disp));
|
| -}
|
| -
|
| -
|
| -FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
|
| - Register array,
|
| - Register index) {
|
| - // Note that index is smi-tagged, (i.e, times 2) for all arrays with element
|
| - // size > 1. For Uint8Array and OneByteString the index is expected to be
|
| - // untagged before accessing.
|
| - ASSERT(kSmiTagShift == 1);
|
| - switch (cid) {
|
| - case kArrayCid:
|
| - case kImmutableArrayCid:
|
| - return FieldAddress(
|
| - array, index, TIMES_HALF_WORD_SIZE, Array::data_offset());
|
| - case kFloat32ArrayCid:
|
| - return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
|
| - case kFloat64ArrayCid:
|
| - return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
|
| - case kInt8ArrayCid:
|
| - return FieldAddress(array, index, TIMES_1, Int8Array::data_offset());
|
| - case kUint8ArrayCid:
|
| - return FieldAddress(array, index, TIMES_1, Uint8Array::data_offset());
|
| - case kUint8ClampedArrayCid:
|
| - return
|
| - FieldAddress(array, index, TIMES_1, Uint8ClampedArray::data_offset());
|
| - case kInt16ArrayCid:
|
| - return FieldAddress(array, index, TIMES_1, Int16Array::data_offset());
|
| - case kUint16ArrayCid:
|
| - return FieldAddress(array, index, TIMES_1, Uint16Array::data_offset());
|
| - case kOneByteStringCid:
|
| - return FieldAddress(array, index, TIMES_1, OneByteString::data_offset());
|
| - case kTwoByteStringCid:
|
| - return FieldAddress(array, index, TIMES_1, TwoByteString::data_offset());
|
| - default:
|
| - UNIMPLEMENTED();
|
| - return FieldAddress(SPREG, 0);
|
| - }
|
| -}
|
| -
|
| -
|
| -Address FlowGraphCompiler::ExternalElementAddressForIntIndex(intptr_t cid,
|
| - Register array,
|
| - intptr_t index) {
|
| - return Address(array, index * ElementSizeFor(cid));
|
| -}
|
| -
|
| -
|
| -Address FlowGraphCompiler::ExternalElementAddressForRegIndex(intptr_t cid,
|
| - Register array,
|
| - Register index) {
|
| - switch (cid) {
|
| - case kExternalUint8ArrayCid:
|
| - return Address(array, index, TIMES_1, 0);
|
| - default:
|
| - UNIMPLEMENTED();
|
| - return Address(SPREG, 0);
|
| - }
|
| -}
|
| -
|
| -
|
| // Returns true if checking against this type is a direct class id comparison.
|
| bool FlowGraphCompiler::TypeCheckAsClassEquality(const AbstractType& type) {
|
| ASSERT(type.IsFinalized() && !type.IsMalformed());
|
| @@ -1187,4 +958,34 @@
|
| return true;
|
| }
|
|
|
| +
|
| +// Returns 'sorted' array in decreasing count order.
|
| +// The expected number of elements to sort is less than 10.
|
| +void FlowGraphCompiler::SortICDataByCount(const ICData& ic_data,
|
| + GrowableArray<CidTarget>* sorted) {
|
| + ASSERT(ic_data.num_args_tested() == 1);
|
| + const intptr_t len = ic_data.NumberOfChecks();
|
| + sorted->Clear();
|
| +
|
| + for (int i = 0; i < len; i++) {
|
| + sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
|
| + &Function::ZoneHandle(ic_data.GetTargetAt(i)),
|
| + ic_data.GetCountAt(i)));
|
| + }
|
| + for (int i = 0; i < len; i++) {
|
| + intptr_t largest_ix = i;
|
| + for (int k = i + 1; k < len; k++) {
|
| + if ((*sorted)[largest_ix].count < (*sorted)[k].count) {
|
| + largest_ix = k;
|
| + }
|
| + }
|
| + if (i != largest_ix) {
|
| + // Swap.
|
| + CidTarget temp = (*sorted)[i];
|
| + (*sorted)[i] = (*sorted)[largest_ix];
|
| + (*sorted)[largest_ix] = temp;
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace dart
|
|
|