OLD | NEW |
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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 if (kNumTemps == 1) { | 168 if (kNumTemps == 1) { |
169 locs->set_temp(0, Location::RequiresRegister()); | 169 locs->set_temp(0, Location::RequiresRegister()); |
170 } | 170 } |
171 return locs; | 171 return locs; |
172 } | 172 } |
173 | 173 |
174 | 174 |
175 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 175 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
176 // The register allocator drops constant definitions that have no uses. | 176 // The register allocator drops constant definitions that have no uses. |
177 if (!locs()->out(0).IsInvalid()) { | 177 if (!locs()->out(0).IsInvalid()) { |
178 XmmRegister result = locs()->out(0).fpu_reg(); | 178 switch (representation()) { |
179 if (constant_address() == 0) { | 179 case kUnboxedDouble: { |
180 Register boxed = locs()->temp(0).reg(); | 180 XmmRegister result = locs()->out(0).fpu_reg(); |
181 __ LoadObjectSafely(boxed, value()); | 181 if (constant_address() == 0) { |
182 __ movsd(result, FieldAddress(boxed, Double::value_offset())); | 182 Register boxed = locs()->temp(0).reg(); |
183 } else if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { | 183 __ LoadObjectSafely(boxed, value()); |
184 __ xorps(result, result); | 184 __ movsd(result, FieldAddress(boxed, Double::value_offset())); |
185 } else { | 185 } else if (Utils::DoublesBitEqual(Double::Cast(value()).value(), 0.0)) { |
186 __ movsd(result, Address::Absolute(constant_address())); | 186 __ xorps(result, result); |
| 187 } else { |
| 188 __ movsd(result, Address::Absolute(constant_address())); |
| 189 } |
| 190 break; |
| 191 } |
| 192 case kUnboxedInt32: |
| 193 __ movl(locs()->out(0).reg(), Immediate(Smi::Cast(value()).Value())); |
| 194 break; |
| 195 default: |
| 196 UNREACHABLE(); |
187 } | 197 } |
188 } | 198 } |
189 } | 199 } |
190 | 200 |
191 | 201 |
192 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, | 202 LocationSummary* AssertAssignableInstr::MakeLocationSummary(Isolate* isolate, |
193 bool opt) const { | 203 bool opt) const { |
194 const intptr_t kNumInputs = 3; | 204 const intptr_t kNumInputs = 3; |
195 const intptr_t kNumTemps = 0; | 205 const intptr_t kNumTemps = 0; |
196 LocationSummary* summary = new(isolate) LocationSummary( | 206 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 | 1045 |
1036 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate, | 1046 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate, |
1037 bool opt) const { | 1047 bool opt) const { |
1038 const intptr_t kNumInputs = 2; | 1048 const intptr_t kNumInputs = 2; |
1039 const intptr_t kNumTemps = 0; | 1049 const intptr_t kNumTemps = 0; |
1040 LocationSummary* locs = new(isolate) LocationSummary( | 1050 LocationSummary* locs = new(isolate) LocationSummary( |
1041 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1051 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1042 locs->set_in(0, Location::RequiresRegister()); | 1052 locs->set_in(0, Location::RequiresRegister()); |
1043 if (CanBeImmediateIndex(index(), class_id())) { | 1053 if (CanBeImmediateIndex(index(), class_id())) { |
1044 // CanBeImmediateIndex must return false for unsafe smis. | 1054 // CanBeImmediateIndex must return false for unsafe smis. |
1045 locs->set_in(1, Location::Constant(index()->BoundConstant())); | 1055 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); |
1046 } else { | 1056 } else { |
1047 // The index is either untagged (element size == 1) or a smi (for all | 1057 // The index is either untagged (element size == 1) or a smi (for all |
1048 // element sizes > 1). | 1058 // element sizes > 1). |
1049 locs->set_in(1, (index_scale() == 1) | 1059 locs->set_in(1, (index_scale() == 1) |
1050 ? Location::WritableRegister() | 1060 ? Location::WritableRegister() |
1051 : Location::RequiresRegister()); | 1061 : Location::RequiresRegister()); |
1052 } | 1062 } |
1053 if ((representation() == kUnboxedDouble) || | 1063 if ((representation() == kUnboxedDouble) || |
1054 (representation() == kUnboxedFloat32x4) || | 1064 (representation() == kUnboxedFloat32x4) || |
1055 (representation() == kUnboxedInt32x4) || | 1065 (representation() == kUnboxedInt32x4) || |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 | 1241 |
1232 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate, | 1242 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate, |
1233 bool opt) const { | 1243 bool opt) const { |
1234 const intptr_t kNumInputs = 3; | 1244 const intptr_t kNumInputs = 3; |
1235 const intptr_t kNumTemps = 0; | 1245 const intptr_t kNumTemps = 0; |
1236 LocationSummary* locs = new(isolate) LocationSummary( | 1246 LocationSummary* locs = new(isolate) LocationSummary( |
1237 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1247 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1238 locs->set_in(0, Location::RequiresRegister()); | 1248 locs->set_in(0, Location::RequiresRegister()); |
1239 if (CanBeImmediateIndex(index(), class_id())) { | 1249 if (CanBeImmediateIndex(index(), class_id())) { |
1240 // CanBeImmediateIndex must return false for unsafe smis. | 1250 // CanBeImmediateIndex must return false for unsafe smis. |
1241 locs->set_in(1, Location::Constant(index()->BoundConstant())); | 1251 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); |
1242 } else { | 1252 } else { |
1243 // The index is either untagged (element size == 1) or a smi (for all | 1253 // The index is either untagged (element size == 1) or a smi (for all |
1244 // element sizes > 1). | 1254 // element sizes > 1). |
1245 locs->set_in(1, (index_scale() == 1) | 1255 locs->set_in(1, (index_scale() == 1) |
1246 ? Location::WritableRegister() | 1256 ? Location::WritableRegister() |
1247 : Location::RequiresRegister()); | 1257 : Location::RequiresRegister()); |
1248 } | 1258 } |
1249 switch (class_id()) { | 1259 switch (class_id()) { |
1250 case kArrayCid: | 1260 case kArrayCid: |
1251 locs->set_in(2, ShouldEmitStoreBarrier() | 1261 locs->set_in(2, ShouldEmitStoreBarrier() |
(...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 bool opt) const { | 2778 bool opt) const { |
2769 const intptr_t kNumInputs = 2; | 2779 const intptr_t kNumInputs = 2; |
2770 if (op_kind() == Token::kTRUNCDIV) { | 2780 if (op_kind() == Token::kTRUNCDIV) { |
2771 const intptr_t kNumTemps = 1; | 2781 const intptr_t kNumTemps = 1; |
2772 LocationSummary* summary = new(isolate) LocationSummary( | 2782 LocationSummary* summary = new(isolate) LocationSummary( |
2773 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2783 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2774 if (RightIsPowerOfTwoConstant()) { | 2784 if (RightIsPowerOfTwoConstant()) { |
2775 summary->set_in(0, Location::RequiresRegister()); | 2785 summary->set_in(0, Location::RequiresRegister()); |
2776 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2786 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
2777 // The programmer only controls one bit, so the constant is safe. | 2787 // The programmer only controls one bit, so the constant is safe. |
2778 summary->set_in(1, Location::Constant(right_constant->value())); | 2788 summary->set_in(1, Location::Constant(right_constant)); |
2779 summary->set_temp(0, Location::RequiresRegister()); | 2789 summary->set_temp(0, Location::RequiresRegister()); |
2780 summary->set_out(0, Location::SameAsFirstInput()); | 2790 summary->set_out(0, Location::SameAsFirstInput()); |
2781 } else { | 2791 } else { |
2782 // Both inputs must be writable because they will be untagged. | 2792 // Both inputs must be writable because they will be untagged. |
2783 summary->set_in(0, Location::RegisterLocation(EAX)); | 2793 summary->set_in(0, Location::RegisterLocation(EAX)); |
2784 summary->set_in(1, Location::WritableRegister()); | 2794 summary->set_in(1, Location::WritableRegister()); |
2785 summary->set_out(0, Location::SameAsFirstInput()); | 2795 summary->set_out(0, Location::SameAsFirstInput()); |
2786 // Will be used for sign extension and division. | 2796 // Will be used for sign extension and division. |
2787 summary->set_temp(0, Location::RegisterLocation(EDX)); | 2797 summary->set_temp(0, Location::RegisterLocation(EDX)); |
2788 } | 2798 } |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3132 UNREACHABLE(); | 3142 UNREACHABLE(); |
3133 break; | 3143 break; |
3134 } | 3144 } |
3135 default: | 3145 default: |
3136 UNREACHABLE(); | 3146 UNREACHABLE(); |
3137 break; | 3147 break; |
3138 } | 3148 } |
3139 } | 3149 } |
3140 | 3150 |
3141 | 3151 |
| 3152 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 3153 bool opt) const { |
| 3154 const intptr_t kNumInputs = 2; |
| 3155 if (op_kind() == Token::kTRUNCDIV) { |
| 3156 UNREACHABLE(); |
| 3157 return NULL; |
| 3158 } else if (op_kind() == Token::kMOD) { |
| 3159 UNREACHABLE(); |
| 3160 return NULL; |
| 3161 } else if (op_kind() == Token::kSHR) { |
| 3162 const intptr_t kNumTemps = 0; |
| 3163 LocationSummary* summary = new(isolate) LocationSummary( |
| 3164 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3165 summary->set_in(0, Location::RequiresRegister()); |
| 3166 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); |
| 3167 summary->set_out(0, Location::SameAsFirstInput()); |
| 3168 return summary; |
| 3169 } else if (op_kind() == Token::kSHL) { |
| 3170 const intptr_t kNumTemps = !IsTruncating() ? 1 : 0; |
| 3171 LocationSummary* summary = new(isolate) LocationSummary( |
| 3172 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3173 summary->set_in(0, Location::RequiresRegister()); |
| 3174 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); |
| 3175 if (!IsTruncating()) { |
| 3176 summary->set_temp(0, Location::RequiresRegister()); |
| 3177 } |
| 3178 summary->set_out(0, Location::SameAsFirstInput()); |
| 3179 return summary; |
| 3180 } else { |
| 3181 const intptr_t kNumTemps = 0; |
| 3182 LocationSummary* summary = new(isolate) LocationSummary( |
| 3183 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3184 summary->set_in(0, Location::RequiresRegister()); |
| 3185 ConstantInstr* constant = right()->definition()->AsConstant(); |
| 3186 if (constant != NULL) { |
| 3187 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 3188 } else { |
| 3189 summary->set_in(1, Location::PrefersRegister()); |
| 3190 } |
| 3191 summary->set_out(0, Location::SameAsFirstInput()); |
| 3192 return summary; |
| 3193 } |
| 3194 } |
| 3195 |
| 3196 |
| 3197 static void EmitInt32ShiftLeft(FlowGraphCompiler* compiler, |
| 3198 BinaryInt32OpInstr* shift_left) { |
| 3199 const bool is_truncating = shift_left->IsTruncating(); |
| 3200 const LocationSummary& locs = *shift_left->locs(); |
| 3201 Register left = locs.in(0).reg(); |
| 3202 Register result = locs.out(0).reg(); |
| 3203 ASSERT(left == result); |
| 3204 Label* deopt = shift_left->CanDeoptimize() ? |
| 3205 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 3206 : NULL; |
| 3207 ASSERT(locs.in(1).IsConstant()); |
| 3208 |
| 3209 const Object& constant = locs.in(1).constant(); |
| 3210 ASSERT(constant.IsSmi()); |
| 3211 // shll operation masks the count to 5 bits. |
| 3212 const intptr_t kCountLimit = 0x1F; |
| 3213 const intptr_t value = Smi::Cast(constant).Value(); |
| 3214 if (value == 0) { |
| 3215 // No code needed. |
| 3216 } else if ((value < 0) || (value >= kCountLimit)) { |
| 3217 // This condition may not be known earlier in some cases because |
| 3218 // of constant propagation, inlining, etc. |
| 3219 if ((value >= kCountLimit) && is_truncating) { |
| 3220 __ xorl(result, result); |
| 3221 } else { |
| 3222 // Result is Mint or exception. |
| 3223 __ jmp(deopt); |
| 3224 } |
| 3225 } else { |
| 3226 if (!is_truncating) { |
| 3227 // Check for overflow. |
| 3228 Register temp = locs.temp(0).reg(); |
| 3229 __ movl(temp, left); |
| 3230 __ shll(left, Immediate(value)); |
| 3231 __ sarl(left, Immediate(value)); |
| 3232 __ cmpl(left, temp); |
| 3233 __ j(NOT_EQUAL, deopt); // Overflow. |
| 3234 } |
| 3235 // Shift for result now we know there is no overflow. |
| 3236 __ shll(left, Immediate(value)); |
| 3237 } |
| 3238 } |
| 3239 |
| 3240 |
| 3241 void BinaryInt32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3242 if (op_kind() == Token::kSHL) { |
| 3243 EmitInt32ShiftLeft(compiler, this); |
| 3244 return; |
| 3245 } |
| 3246 |
| 3247 Register left = locs()->in(0).reg(); |
| 3248 Register result = locs()->out(0).reg(); |
| 3249 ASSERT(left == result); |
| 3250 Label* deopt = NULL; |
| 3251 if (CanDeoptimize()) { |
| 3252 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 3253 } |
| 3254 |
| 3255 if (locs()->in(1).IsConstant()) { |
| 3256 const Object& constant = locs()->in(1).constant(); |
| 3257 ASSERT(constant.IsSmi()); |
| 3258 const intptr_t value = Smi::Cast(constant).Value(); |
| 3259 switch (op_kind()) { |
| 3260 case Token::kADD: |
| 3261 if (value != 0) { |
| 3262 // Checking overflow without emitting an instruction would be wrong. |
| 3263 __ addl(left, Immediate(value)); |
| 3264 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3265 } |
| 3266 break; |
| 3267 case Token::kSUB: { |
| 3268 if (value != 0) { |
| 3269 // Checking overflow without emitting an instruction would be wrong. |
| 3270 __ subl(left, Immediate(value)); |
| 3271 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3272 } |
| 3273 break; |
| 3274 } |
| 3275 case Token::kMUL: { |
| 3276 if (value == 2) { |
| 3277 __ shll(left, Immediate(1)); |
| 3278 } else { |
| 3279 __ imull(left, Immediate(value)); |
| 3280 } |
| 3281 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3282 break; |
| 3283 } |
| 3284 case Token::kTRUNCDIV: { |
| 3285 UNREACHABLE(); |
| 3286 break; |
| 3287 } |
| 3288 case Token::kBIT_AND: { |
| 3289 // No overflow check. |
| 3290 __ andl(left, Immediate(value)); |
| 3291 break; |
| 3292 } |
| 3293 case Token::kBIT_OR: { |
| 3294 // No overflow check. |
| 3295 __ orl(left, Immediate(value)); |
| 3296 break; |
| 3297 } |
| 3298 case Token::kBIT_XOR: { |
| 3299 // No overflow check. |
| 3300 __ xorl(left, Immediate(value)); |
| 3301 break; |
| 3302 } |
| 3303 case Token::kSHR: { |
| 3304 // sarl operation masks the count to 5 bits. |
| 3305 const intptr_t kCountLimit = 0x1F; |
| 3306 if (value == 0) { |
| 3307 // TODO(vegorov): should be handled outside. |
| 3308 break; |
| 3309 } else if (value < 0) { |
| 3310 // TODO(vegorov): should be handled outside. |
| 3311 __ jmp(deopt); |
| 3312 break; |
| 3313 } |
| 3314 |
| 3315 if (value >= kCountLimit) { |
| 3316 __ sarl(left, Immediate(kCountLimit)); |
| 3317 } else { |
| 3318 __ sarl(left, Immediate(value)); |
| 3319 } |
| 3320 |
| 3321 break; |
| 3322 } |
| 3323 |
| 3324 default: |
| 3325 UNREACHABLE(); |
| 3326 break; |
| 3327 } |
| 3328 return; |
| 3329 } // if locs()->in(1).IsConstant() |
| 3330 |
| 3331 if (locs()->in(1).IsStackSlot()) { |
| 3332 const Address& right = locs()->in(1).ToStackSlotAddress(); |
| 3333 switch (op_kind()) { |
| 3334 case Token::kADD: { |
| 3335 __ addl(left, right); |
| 3336 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3337 break; |
| 3338 } |
| 3339 case Token::kSUB: { |
| 3340 __ subl(left, right); |
| 3341 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3342 break; |
| 3343 } |
| 3344 case Token::kMUL: { |
| 3345 __ imull(left, right); |
| 3346 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3347 break; |
| 3348 } |
| 3349 case Token::kBIT_AND: { |
| 3350 // No overflow check. |
| 3351 __ andl(left, right); |
| 3352 break; |
| 3353 } |
| 3354 case Token::kBIT_OR: { |
| 3355 // No overflow check. |
| 3356 __ orl(left, right); |
| 3357 break; |
| 3358 } |
| 3359 case Token::kBIT_XOR: { |
| 3360 // No overflow check. |
| 3361 __ xorl(left, right); |
| 3362 break; |
| 3363 } |
| 3364 default: |
| 3365 UNREACHABLE(); |
| 3366 } |
| 3367 return; |
| 3368 } // if locs()->in(1).IsStackSlot. |
| 3369 |
| 3370 // if locs()->in(1).IsRegister. |
| 3371 Register right = locs()->in(1).reg(); |
| 3372 switch (op_kind()) { |
| 3373 case Token::kADD: { |
| 3374 __ addl(left, right); |
| 3375 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3376 break; |
| 3377 } |
| 3378 case Token::kSUB: { |
| 3379 __ subl(left, right); |
| 3380 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3381 break; |
| 3382 } |
| 3383 case Token::kMUL: { |
| 3384 __ imull(left, right); |
| 3385 if (deopt != NULL) __ j(OVERFLOW, deopt); |
| 3386 break; |
| 3387 } |
| 3388 case Token::kBIT_AND: { |
| 3389 // No overflow check. |
| 3390 __ andl(left, right); |
| 3391 break; |
| 3392 } |
| 3393 case Token::kBIT_OR: { |
| 3394 // No overflow check. |
| 3395 __ orl(left, right); |
| 3396 break; |
| 3397 } |
| 3398 case Token::kBIT_XOR: { |
| 3399 // No overflow check. |
| 3400 __ xorl(left, right); |
| 3401 break; |
| 3402 } |
| 3403 case Token::kTRUNCDIV: { |
| 3404 UNREACHABLE(); |
| 3405 break; |
| 3406 } |
| 3407 case Token::kMOD: { |
| 3408 UNREACHABLE(); |
| 3409 break; |
| 3410 } |
| 3411 case Token::kSHR: { |
| 3412 UNREACHABLE(); |
| 3413 break; |
| 3414 } |
| 3415 case Token::kDIV: { |
| 3416 // Dispatches to 'Double./'. |
| 3417 // TODO(srdjan): Implement as conversion to double and double division. |
| 3418 UNREACHABLE(); |
| 3419 break; |
| 3420 } |
| 3421 case Token::kOR: |
| 3422 case Token::kAND: { |
| 3423 // Flow graph builder has dissected this operation to guarantee correct |
| 3424 // behavior (short-circuit evaluation). |
| 3425 UNREACHABLE(); |
| 3426 break; |
| 3427 } |
| 3428 default: |
| 3429 UNREACHABLE(); |
| 3430 break; |
| 3431 } |
| 3432 } |
| 3433 |
| 3434 |
3142 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Isolate* isolate, | 3435 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary(Isolate* isolate, |
3143 bool opt) const { | 3436 bool opt) const { |
3144 intptr_t left_cid = left()->Type()->ToCid(); | 3437 intptr_t left_cid = left()->Type()->ToCid(); |
3145 intptr_t right_cid = right()->Type()->ToCid(); | 3438 intptr_t right_cid = right()->Type()->ToCid(); |
3146 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); | 3439 ASSERT((left_cid != kDoubleCid) && (right_cid != kDoubleCid)); |
3147 const intptr_t kNumInputs = 2; | 3440 const intptr_t kNumInputs = 2; |
3148 const bool need_temp = (left()->definition() != right()->definition()) | 3441 const bool need_temp = (left()->definition() != right()->definition()) |
3149 && (left_cid != kSmiCid) | 3442 && (left_cid != kSmiCid) |
3150 && (right_cid != kSmiCid); | 3443 && (right_cid != kSmiCid); |
3151 const intptr_t kNumTemps = need_temp ? 1 : 0; | 3444 const intptr_t kNumTemps = need_temp ? 1 : 0; |
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4666 } | 4959 } |
4667 | 4960 |
4668 | 4961 |
4669 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4962 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4670 XmmRegister value = locs()->in(0).fpu_reg(); | 4963 XmmRegister value = locs()->in(0).fpu_reg(); |
4671 ASSERT(locs()->out(0).fpu_reg() == value); | 4964 ASSERT(locs()->out(0).fpu_reg() == value); |
4672 __ DoubleNegate(value); | 4965 __ DoubleNegate(value); |
4673 } | 4966 } |
4674 | 4967 |
4675 | 4968 |
| 4969 LocationSummary* Int32ToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
| 4970 bool opt) const { |
| 4971 const intptr_t kNumInputs = 1; |
| 4972 const intptr_t kNumTemps = 0; |
| 4973 LocationSummary* result = new(isolate) LocationSummary( |
| 4974 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4975 result->set_in(0, Location::WritableRegister()); |
| 4976 result->set_out(0, Location::RequiresFpuRegister()); |
| 4977 return result; |
| 4978 } |
| 4979 |
| 4980 |
| 4981 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4982 Register value = locs()->in(0).reg(); |
| 4983 FpuRegister result = locs()->out(0).fpu_reg(); |
| 4984 __ cvtsi2sd(result, value); |
| 4985 } |
| 4986 |
| 4987 |
4676 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, | 4988 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, |
4677 bool opt) const { | 4989 bool opt) const { |
4678 const intptr_t kNumInputs = 1; | 4990 const intptr_t kNumInputs = 1; |
4679 const intptr_t kNumTemps = 0; | 4991 const intptr_t kNumTemps = 0; |
4680 LocationSummary* result = new(isolate) LocationSummary( | 4992 LocationSummary* result = new(isolate) LocationSummary( |
4681 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4993 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4682 result->set_in(0, Location::WritableRegister()); | 4994 result->set_in(0, Location::WritableRegister()); |
4683 result->set_out(0, Location::RequiresFpuRegister()); | 4995 result->set_out(0, Location::RequiresFpuRegister()); |
4684 return result; | 4996 return result; |
4685 } | 4997 } |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5903 CompileType ShiftUint32OpInstr::ComputeType() const { | 6215 CompileType ShiftUint32OpInstr::ComputeType() const { |
5904 return CompileType::Int(); | 6216 return CompileType::Int(); |
5905 } | 6217 } |
5906 | 6218 |
5907 | 6219 |
5908 CompileType UnaryUint32OpInstr::ComputeType() const { | 6220 CompileType UnaryUint32OpInstr::ComputeType() const { |
5909 return CompileType::Int(); | 6221 return CompileType::Int(); |
5910 } | 6222 } |
5911 | 6223 |
5912 | 6224 |
5913 CompileType BoxUint32Instr::ComputeType() const { | |
5914 return CompileType::Int(); | |
5915 } | |
5916 | |
5917 | |
5918 CompileType UnboxUint32Instr::ComputeType() const { | |
5919 return CompileType::Int(); | |
5920 } | |
5921 | |
5922 | |
5923 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | 6225 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, |
5924 bool opt) const { | 6226 bool opt) const { |
5925 const intptr_t kNumInputs = 2; | 6227 const intptr_t kNumInputs = 2; |
5926 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; | 6228 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0; |
5927 LocationSummary* summary = new(isolate) LocationSummary( | 6229 LocationSummary* summary = new(isolate) LocationSummary( |
5928 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6230 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5929 if (op_kind() == Token::kMUL) { | 6231 if (op_kind() == Token::kMUL) { |
5930 summary->set_in(0, Location::RegisterLocation(EAX)); | 6232 summary->set_in(0, Location::RegisterLocation(EAX)); |
5931 summary->set_temp(0, Location::RegisterLocation(EDX)); | 6233 summary->set_temp(0, Location::RegisterLocation(EDX)); |
5932 } else { | 6234 } else { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6085 | 6387 |
6086 __ notl(out); | 6388 __ notl(out); |
6087 } | 6389 } |
6088 | 6390 |
6089 | 6391 |
6090 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6392 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, |
6091 bool opt) const { | 6393 bool opt) const { |
6092 const intptr_t kNumInputs = 1; | 6394 const intptr_t kNumInputs = 1; |
6093 const intptr_t kNumTemps = 0; | 6395 const intptr_t kNumTemps = 0; |
6094 LocationSummary* summary = new(isolate) LocationSummary( | 6396 LocationSummary* summary = new(isolate) LocationSummary( |
6095 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 6397 isolate, |
| 6398 kNumInputs, |
| 6399 kNumTemps, |
| 6400 ValueFitsSmi() ? LocationSummary::kNoCall |
| 6401 : LocationSummary::kCallOnSlowPath); |
6096 summary->set_in(0, Location::RequiresRegister()); | 6402 summary->set_in(0, Location::RequiresRegister()); |
6097 summary->set_out(0, Location::RequiresRegister()); | 6403 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() |
| 6404 : Location::RequiresRegister()); |
6098 return summary; | 6405 return summary; |
6099 } | 6406 } |
6100 | 6407 |
6101 | 6408 |
6102 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6409 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6103 Register value = locs()->in(0).reg(); | 6410 Register value = locs()->in(0).reg(); |
6104 Register out = locs()->out(0).reg(); | 6411 Register out = locs()->out(0).reg(); |
6105 ASSERT(value != out); | |
6106 | 6412 |
6107 Label not_smi, done; | 6413 Label not_smi, done; |
6108 | 6414 |
6109 // TODO(johnmccutchan): Use range information to fast path smi / mint boxing. | 6415 if (ValueFitsSmi()) { |
6110 // Test if this value is <= kSmiMax. | 6416 ASSERT(value == out); |
6111 __ cmpl(value, Immediate(kSmiMax)); | 6417 __ SmiTag(value); |
6112 __ j(ABOVE, ¬_smi); | 6418 } else { |
6113 // Smi. | 6419 ASSERT(value != out); |
6114 __ movl(out, value); | 6420 __ cmpl(value, Immediate(kSmiMax)); |
6115 __ SmiTag(out); | 6421 __ j(ABOVE, ¬_smi); |
6116 __ jmp(&done); | 6422 // Smi. |
6117 __ Bind(¬_smi); | 6423 __ movl(out, value); |
6118 // Allocate a mint. | 6424 __ SmiTag(out); |
6119 BoxAllocationSlowPath::Allocate( | 6425 __ jmp(&done); |
6120 compiler, this, compiler->mint_class(), out, kNoRegister); | 6426 __ Bind(¬_smi); |
6121 // Copy low word into mint. | 6427 // Allocate a mint. |
6122 __ movl(FieldAddress(out, Mint::value_offset()), value); | 6428 BoxAllocationSlowPath::Allocate( |
6123 // Zero high word. | 6429 compiler, this, compiler->mint_class(), out, kNoRegister); |
6124 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); | 6430 // Copy low word into mint. |
6125 __ Bind(&done); | 6431 __ movl(FieldAddress(out, Mint::value_offset()), value); |
| 6432 // Zero high word. |
| 6433 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); |
| 6434 __ Bind(&done); |
| 6435 } |
6126 } | 6436 } |
6127 | 6437 |
6128 | 6438 |
| 6439 LocationSummary* BoxInt32Instr::MakeLocationSummary(Isolate* isolate, |
| 6440 bool opt) const { |
| 6441 const intptr_t kNumInputs = 1; |
| 6442 const intptr_t kNumTemps = 0; |
| 6443 LocationSummary* summary = new(isolate) LocationSummary( |
| 6444 isolate, kNumInputs, kNumTemps, |
| 6445 ValueFitsSmi() ? LocationSummary::kNoCall |
| 6446 : LocationSummary::kCallOnSlowPath); |
| 6447 summary->set_in(0, ValueFitsSmi() ? Location::RequiresRegister() |
| 6448 : Location::WritableRegister()); |
| 6449 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() |
| 6450 : Location::RequiresRegister()); |
| 6451 return summary; |
| 6452 } |
| 6453 |
| 6454 |
| 6455 void BoxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6456 Register value = locs()->in(0).reg(); |
| 6457 Register out = locs()->out(0).reg(); |
| 6458 |
| 6459 if (out != value) { |
| 6460 __ movl(out, value); |
| 6461 } |
| 6462 __ shll(out, Immediate(1)); |
| 6463 if (!ValueFitsSmi()) { |
| 6464 Label done; |
| 6465 __ j(NO_OVERFLOW, &done); |
| 6466 // Allocate a mint. |
| 6467 BoxAllocationSlowPath::Allocate( |
| 6468 compiler, this, compiler->mint_class(), out, kNoRegister); |
| 6469 __ movl(FieldAddress(out, Mint::value_offset()), value); |
| 6470 __ sarl(value, Immediate(31)); // Sign extend. |
| 6471 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); |
| 6472 __ Bind(&done); |
| 6473 } |
| 6474 } |
| 6475 |
| 6476 |
6129 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6477 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, |
6130 bool opt) const { | 6478 bool opt) const { |
6131 const intptr_t value_cid = value()->Type()->ToCid(); | 6479 const intptr_t value_cid = value()->Type()->ToCid(); |
6132 const intptr_t kNumInputs = 1; | 6480 const intptr_t kNumInputs = 1; |
6133 const intptr_t kNumTemps = | 6481 const intptr_t kNumTemps = |
6134 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | 6482 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; |
6135 LocationSummary* summary = new(isolate) LocationSummary( | 6483 LocationSummary* summary = new(isolate) LocationSummary( |
6136 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6484 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6137 summary->set_in(0, Location::RequiresRegister()); | 6485 summary->set_in(0, Location::RequiresRegister()); |
6138 if (kNumTemps > 0) { | 6486 if (kNumTemps > 0) { |
(...skipping 25 matching lines...) Expand all Loading... |
6164 __ j(NOT_EQUAL, deopt); | 6512 __ j(NOT_EQUAL, deopt); |
6165 __ movl(value, FieldAddress(value, Mint::value_offset())); | 6513 __ movl(value, FieldAddress(value, Mint::value_offset())); |
6166 __ jmp(&done); | 6514 __ jmp(&done); |
6167 __ Bind(&is_smi); | 6515 __ Bind(&is_smi); |
6168 __ SmiUntag(value); | 6516 __ SmiUntag(value); |
6169 __ Bind(&done); | 6517 __ Bind(&done); |
6170 } | 6518 } |
6171 } | 6519 } |
6172 | 6520 |
6173 | 6521 |
| 6522 LocationSummary* UnboxInt32Instr::MakeLocationSummary(Isolate* isolate, |
| 6523 bool opt) const { |
| 6524 const intptr_t value_cid = value()->Type()->ToCid(); |
| 6525 const intptr_t kNumInputs = 1; |
| 6526 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; |
| 6527 LocationSummary* summary = new(isolate) LocationSummary( |
| 6528 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6529 summary->set_in(0, Location::RequiresRegister()); |
| 6530 if (kNumTemps > 0) { |
| 6531 summary->set_temp(0, Location::RequiresRegister()); |
| 6532 } |
| 6533 summary->set_out(0, (value_cid == kSmiCid) ? Location::SameAsFirstInput() |
| 6534 : Location::RequiresRegister()); |
| 6535 return summary; |
| 6536 } |
| 6537 |
| 6538 |
| 6539 static void LoadInt32FromMint(FlowGraphCompiler* compiler, |
| 6540 Register mint, |
| 6541 Register result, |
| 6542 Register temp, |
| 6543 Label* deopt) { |
| 6544 __ movl(result, FieldAddress(mint, Mint::value_offset())); |
| 6545 if (deopt != NULL) { |
| 6546 __ movl(temp, result); |
| 6547 __ sarl(temp, Immediate(31)); |
| 6548 __ cmpl(temp, FieldAddress(mint, Mint::value_offset() + kWordSize)); |
| 6549 __ j(NOT_EQUAL, deopt); |
| 6550 } |
| 6551 } |
| 6552 |
| 6553 |
| 6554 void UnboxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6555 const intptr_t value_cid = value()->Type()->ToCid(); |
| 6556 const Register value = locs()->in(0).reg(); |
| 6557 const Register result = locs()->out(0).reg(); |
| 6558 |
| 6559 // TODO(johnmccutchan): Emit better code for constant inputs. |
| 6560 if (value_cid == kMintCid) { |
| 6561 Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; |
| 6562 Label* deopt = CanDeoptimize() ? |
| 6563 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; |
| 6564 LoadInt32FromMint(compiler, |
| 6565 value, |
| 6566 result, |
| 6567 temp, |
| 6568 deopt); |
| 6569 } else if (value_cid == kSmiCid) { |
| 6570 ASSERT(value == result); |
| 6571 __ SmiUntag(value); |
| 6572 } else { |
| 6573 Register temp = locs()->temp(0).reg(); |
| 6574 Label* deopt = compiler->AddDeoptStub(deopt_id_, |
| 6575 ICData::kDeoptUnboxInteger); |
| 6576 Label is_smi, done; |
| 6577 __ testl(value, Immediate(kSmiTagMask)); |
| 6578 __ j(ZERO, &is_smi); |
| 6579 __ CompareClassId(value, kMintCid, temp); |
| 6580 __ j(NOT_EQUAL, deopt); |
| 6581 LoadInt32FromMint(compiler, |
| 6582 value, |
| 6583 result, |
| 6584 temp, |
| 6585 deopt); |
| 6586 __ movl(value, FieldAddress(value, Mint::value_offset())); |
| 6587 __ jmp(&done); |
| 6588 __ Bind(&is_smi); |
| 6589 __ SmiUntag(value); |
| 6590 __ Bind(&done); |
| 6591 } |
| 6592 } |
| 6593 |
| 6594 |
6174 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6595 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
6175 bool opt) const { | 6596 bool opt) const { |
6176 const intptr_t kNumInputs = 1; | 6597 const intptr_t kNumInputs = 1; |
6177 const intptr_t kNumTemps = 0; | 6598 const intptr_t kNumTemps = 0; |
6178 LocationSummary* summary = new(isolate) LocationSummary( | 6599 LocationSummary* summary = new(isolate) LocationSummary( |
6179 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6600 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6180 if (from() == kUnboxedMint) { | 6601 if ((from() == kUnboxedInt32 || from() == kUnboxedUint32) && |
6181 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6602 (to() == kUnboxedInt32 || to() == kUnboxedUint32)) { |
6182 Location::RequiresRegister())); | 6603 summary->set_in(0, Location::RequiresRegister()); |
| 6604 summary->set_out(0, Location::SameAsFirstInput()); |
| 6605 } else if (from() == kUnboxedMint) { |
| 6606 summary->set_in(0, Location::Pair( |
| 6607 CanDeoptimize() ? Location::WritableRegister() |
| 6608 : Location::RequiresRegister(), |
| 6609 Location::RequiresRegister())); |
6183 summary->set_out(0, Location::RequiresRegister()); | 6610 summary->set_out(0, Location::RequiresRegister()); |
6184 } else { | 6611 } else if (from() == kUnboxedUint32) { |
6185 ASSERT(from() == kUnboxedUint32); | |
6186 summary->set_in(0, Location::RequiresRegister()); | 6612 summary->set_in(0, Location::RequiresRegister()); |
6187 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | 6613 summary->set_out(0, Location::Pair(Location::RequiresRegister(), |
6188 Location::RequiresRegister())); | 6614 Location::RequiresRegister())); |
| 6615 } else if (from() == kUnboxedInt32) { |
| 6616 summary->set_in(0, Location::RegisterLocation(EAX)); |
| 6617 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX), |
| 6618 Location::RegisterLocation(EDX))); |
6189 } | 6619 } |
6190 return summary; | 6620 return summary; |
6191 } | 6621 } |
6192 | 6622 |
6193 | 6623 |
6194 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6624 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6195 if (from() == kUnboxedMint) { | 6625 if (from() == kUnboxedInt32 && to() == kUnboxedUint32) { |
| 6626 // Representations are bitwise equivalent. |
| 6627 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); |
| 6628 } else if (from() == kUnboxedUint32 && to() == kUnboxedInt32) { |
| 6629 // Representations are bitwise equivalent. |
| 6630 ASSERT(locs()->out(0).reg() == locs()->in(0).reg()); |
| 6631 if (CanDeoptimize()) { |
| 6632 Label* deopt = |
| 6633 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6634 __ testl(locs()->out(0).reg(), locs()->out(0).reg()); |
| 6635 __ j(NEGATIVE, deopt); |
| 6636 } |
| 6637 } else if (from() == kUnboxedMint) { |
| 6638 // TODO(vegorov) kUnboxedMint -> kInt32 conversion is currently usually |
| 6639 // dominated by a CheckSmi(BoxInteger(val)) which is an artifact of ordering |
| 6640 // of optimization passes and the way we check smi-ness of values. |
| 6641 // Optimize it away. |
| 6642 ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32); |
6196 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | 6643 PairLocation* in_pair = locs()->in(0).AsPairLocation(); |
6197 Register in_lo = in_pair->At(0).reg(); | 6644 Register in_lo = in_pair->At(0).reg(); |
| 6645 Register in_hi = in_pair->At(1).reg(); |
6198 Register out = locs()->out(0).reg(); | 6646 Register out = locs()->out(0).reg(); |
6199 // Copy low word. | 6647 // Copy low word. |
6200 __ movl(out, in_lo); | 6648 __ movl(out, in_lo); |
6201 } else { | 6649 if (CanDeoptimize()) { |
6202 ASSERT(from() == kUnboxedUint32); | 6650 Label* deopt = |
| 6651 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnboxInteger); |
| 6652 __ sarl(in_lo, Immediate(31)); |
| 6653 __ cmpl(in_lo, in_hi); |
| 6654 __ j(NOT_EQUAL, deopt); |
| 6655 } |
| 6656 } else if (from() == kUnboxedUint32) { |
| 6657 ASSERT(to() == kUnboxedMint); |
6203 Register in = locs()->in(0).reg(); | 6658 Register in = locs()->in(0).reg(); |
6204 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6659 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
6205 Register out_lo = out_pair->At(0).reg(); | 6660 Register out_lo = out_pair->At(0).reg(); |
6206 Register out_hi = out_pair->At(1).reg(); | 6661 Register out_hi = out_pair->At(1).reg(); |
6207 // Copy low word. | 6662 // Copy low word. |
6208 __ movl(out_lo, in); | 6663 __ movl(out_lo, in); |
6209 // Zero upper word. | 6664 // Zero upper word. |
6210 __ xorl(out_hi, out_hi); | 6665 __ xorl(out_hi, out_hi); |
| 6666 } else if (from() == kUnboxedInt32) { |
| 6667 ASSERT(to() == kUnboxedMint); |
| 6668 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6669 Register out_lo = out_pair->At(0).reg(); |
| 6670 Register out_hi = out_pair->At(1).reg(); |
| 6671 ASSERT(locs()->in(0).reg() == EAX); |
| 6672 ASSERT(out_lo == EAX && out_hi == EDX); |
| 6673 __ cdq(); |
| 6674 } else { |
| 6675 UNREACHABLE(); |
6211 } | 6676 } |
6212 } | 6677 } |
6213 | 6678 |
6214 | 6679 |
6215 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 6680 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
6216 bool opt) const { | 6681 bool opt) const { |
6217 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 6682 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |
6218 } | 6683 } |
6219 | 6684 |
6220 | 6685 |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6564 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 7029 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6565 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 7030 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6566 #endif | 7031 #endif |
6567 } | 7032 } |
6568 | 7033 |
6569 } // namespace dart | 7034 } // namespace dart |
6570 | 7035 |
6571 #undef __ | 7036 #undef __ |
6572 | 7037 |
6573 #endif // defined TARGET_ARCH_IA32 | 7038 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |