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

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 12212175: Optimize left shift of a constant: compute max value of right that does not overflow into Mint/Bigi… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 __ movq(right, Immediate(kCountLimit)); 2067 __ movq(right, Immediate(kCountLimit));
2068 __ Bind(&count_ok); 2068 __ Bind(&count_ok);
2069 } 2069 }
2070 ASSERT(right == RCX); // Count must be in RCX 2070 ASSERT(right == RCX); // Count must be in RCX
2071 __ SmiUntag(left); 2071 __ SmiUntag(left);
2072 __ sarq(left, right); 2072 __ sarq(left, right);
2073 __ SmiTag(left); 2073 __ SmiTag(left);
2074 break; 2074 break;
2075 } 2075 }
2076 case Token::kSHL: { 2076 case Token::kSHL: {
2077 Range* right_range = this->right()->definition()->range();
2078 if (this->left()->BindsToConstant()) {
2079 // If left is constant, we know the maximal allowed size for right.
2080 const Object& obj = this->left()->BoundConstant();
2081 if (obj.IsSmi()) {
2082 const intptr_t left_int = Smi::Cast(obj).Value();
2083 if (left_int == 0) {
2084 __ cmpq(right, Immediate(0));
2085 __ j(NEGATIVE, deopt);
2086 break;
2087 }
2088 intptr_t tmp = (left_int > 0) ? left_int : ~left_int;
2089 intptr_t max_right = kSmiBits;
2090 while ((tmp >>= 1) != 0) {
2091 max_right--;
2092 }
2093 const bool right_needs_check =
2094 (right_range == NULL) ||
2095 !right_range->IsWithin(0, max_right - 1);
2096 if (right_needs_check) {
2097 __ cmpq(right,
2098 Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
2099 __ j(ABOVE_EQUAL, deopt);
2100 }
2101 __ SmiUntag(right);
2102 __ shlq(left, right);
2103 break;
2104 }
2105 }
2077 Register temp = locs()->temp(0).reg(); 2106 Register temp = locs()->temp(0).reg();
2078 // Check if count too large for handling it inlined. 2107 // Check if count too large for handling it inlined.
2079 __ movq(temp, left); 2108 __ movq(temp, left);
2080 Range* right_range = this->right()->definition()->range();
2081 const bool right_needs_check = 2109 const bool right_needs_check =
2082 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1)); 2110 (right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1));
2083 if (right_needs_check) { 2111 if (right_needs_check) {
2084 __ cmpq(right, 2112 __ cmpq(right,
2085 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); 2113 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
2086 __ j(ABOVE_EQUAL, deopt); 2114 __ j(ABOVE_EQUAL, deopt);
2087 } 2115 }
2088 ASSERT(right == RCX); // Count must be in RCX 2116 ASSERT(right == RCX); // Count must be in RCX
2089 __ SmiUntag(right); 2117 __ SmiUntag(right);
2090 // Overflow test (preserve temp and right); 2118 // Overflow test (preserve temp and right);
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 PcDescriptors::kOther, 3067 PcDescriptors::kOther,
3040 locs()); 3068 locs());
3041 __ Drop(2); // Discard type arguments and receiver. 3069 __ Drop(2); // Discard type arguments and receiver.
3042 } 3070 }
3043 3071
3044 } // namespace dart 3072 } // namespace dart
3045 3073
3046 #undef __ 3074 #undef __
3047 3075
3048 #endif // defined TARGET_ARCH_X64 3076 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698