OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2269 if (FLAG_allocation_site_pretenuring) { | 2269 if (FLAG_allocation_site_pretenuring) { |
2270 Node* count = LoadObjectField(allocation_site, | 2270 Node* count = LoadObjectField(allocation_site, |
2271 AllocationSite::kPretenureCreateCountOffset); | 2271 AllocationSite::kPretenureCreateCountOffset); |
2272 Node* incremented_count = SmiAdd(count, SmiConstant(Smi::FromInt(1))); | 2272 Node* incremented_count = SmiAdd(count, SmiConstant(Smi::FromInt(1))); |
2273 StoreObjectFieldNoWriteBarrier(allocation_site, | 2273 StoreObjectFieldNoWriteBarrier(allocation_site, |
2274 AllocationSite::kPretenureCreateCountOffset, | 2274 AllocationSite::kPretenureCreateCountOffset, |
2275 incremented_count); | 2275 incremented_count); |
2276 } | 2276 } |
2277 } | 2277 } |
2278 | 2278 |
2279 Node* CodeStubAssembler::TryTaggedToFloat64(Node* value, | |
Igor Sheludko
2016/11/11 16:13:21
Please also this TryTaggedToFloat64() in a kDouble
jgruber
2016/11/13 13:00:09
Will fix.
jgruber
2016/11/15 10:02:29
Done.
| |
2280 Label* if_valueisnotnumber) { | |
2281 Label out(this); | |
2282 Variable var_result(this, MachineRepresentation::kFloat64); | |
2283 var_result.Bind(Float64Constant(0.0)); | |
Igor Sheludko
2016/11/11 16:13:21
Please remove this bind if the CSA does not compla
jgruber
2016/11/13 13:00:09
Will fix.
jgruber
2016/11/15 10:02:29
Done.
| |
2284 | |
2285 // Check if the {value} is a Smi or a HeapObject. | |
2286 Label if_valueissmi(this), if_valueisnotsmi(this); | |
2287 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | |
2288 | |
2289 Bind(&if_valueissmi); | |
2290 { | |
2291 // Convert the Smi {value}. | |
2292 var_result.Bind(SmiToFloat64(value)); | |
2293 Goto(&out); | |
2294 } | |
2295 | |
2296 Bind(&if_valueisnotsmi); | |
2297 { | |
2298 // Check if {value} is a HeapNumber. | |
2299 Label if_valueisheapnumber(this); | |
2300 Branch(WordEqual(LoadMap(value), HeapNumberMapConstant()), | |
Igor Sheludko
2016/11/11 16:13:21
Branch(IsHeapNumberMap(LoadMap(value))),
jgruber
2016/11/13 13:00:09
Will fix.
jgruber
2016/11/15 10:02:29
Done.
| |
2301 &if_valueisheapnumber, if_valueisnotnumber); | |
2302 | |
2303 Bind(&if_valueisheapnumber); | |
2304 { | |
2305 // Load the floating point value. | |
2306 var_result.Bind(LoadHeapNumberValue(value)); | |
2307 Goto(&out); | |
2308 } | |
2309 } | |
2310 Bind(&out); | |
2311 return var_result.value(); | |
2312 } | |
2313 | |
2279 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { | 2314 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { |
2280 // We might need to loop once due to ToNumber conversion. | 2315 // We might need to loop once due to ToNumber conversion. |
2281 Variable var_value(this, MachineRepresentation::kTagged), | 2316 Variable var_value(this, MachineRepresentation::kTagged), |
2282 var_result(this, MachineRepresentation::kFloat64); | 2317 var_result(this, MachineRepresentation::kFloat64); |
2283 Label loop(this, &var_value), done_loop(this, &var_result); | 2318 Label loop(this, &var_value), done_loop(this, &var_result); |
2284 var_value.Bind(value); | 2319 var_value.Bind(value); |
2285 Goto(&loop); | 2320 Goto(&loop); |
2286 Bind(&loop); | 2321 Bind(&loop); |
2287 { | 2322 { |
2323 Label if_valueisnotnumber(this, Label::kDeferred); | |
2324 | |
2288 // Load the current {value}. | 2325 // Load the current {value}. |
2289 value = var_value.value(); | 2326 value = var_value.value(); |
2290 | 2327 |
2291 // Check if the {value} is a Smi or a HeapObject. | 2328 // Convert {value} to Float64 if it is a number and convert it to a number |
2292 Label if_valueissmi(this), if_valueisnotsmi(this); | 2329 // otherwise. |
2293 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 2330 Node* const result = TryTaggedToFloat64(value, &if_valueisnotnumber); |
2331 var_result.Bind(result); | |
2332 Goto(&done_loop); | |
2294 | 2333 |
2295 Bind(&if_valueissmi); | 2334 Bind(&if_valueisnotnumber); |
2296 { | 2335 { |
2297 // Convert the Smi {value}. | 2336 // Convert the {value} to a Number first. |
2298 var_result.Bind(SmiToFloat64(value)); | 2337 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
2299 Goto(&done_loop); | 2338 var_value.Bind(CallStub(callable, context, value)); |
2300 } | 2339 Goto(&loop); |
2301 | |
2302 Bind(&if_valueisnotsmi); | |
2303 { | |
2304 // Check if {value} is a HeapNumber. | |
2305 Label if_valueisheapnumber(this), | |
2306 if_valueisnotheapnumber(this, Label::kDeferred); | |
2307 Branch(WordEqual(LoadMap(value), HeapNumberMapConstant()), | |
2308 &if_valueisheapnumber, &if_valueisnotheapnumber); | |
2309 | |
2310 Bind(&if_valueisheapnumber); | |
2311 { | |
2312 // Load the floating point value. | |
2313 var_result.Bind(LoadHeapNumberValue(value)); | |
2314 Goto(&done_loop); | |
2315 } | |
2316 | |
2317 Bind(&if_valueisnotheapnumber); | |
2318 { | |
2319 // Convert the {value} to a Number first. | |
2320 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | |
2321 var_value.Bind(CallStub(callable, context, value)); | |
2322 Goto(&loop); | |
2323 } | |
2324 } | 2340 } |
2325 } | 2341 } |
2326 Bind(&done_loop); | 2342 Bind(&done_loop); |
2327 return var_result.value(); | 2343 return var_result.value(); |
2328 } | 2344 } |
2329 | 2345 |
2330 Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { | 2346 Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { |
2331 // We might need to loop once due to ToNumber conversion. | 2347 // We might need to loop once due to ToNumber conversion. |
2332 Variable var_value(this, MachineRepresentation::kTagged), | 2348 Variable var_value(this, MachineRepresentation::kTagged), |
2333 var_result(this, MachineRepresentation::kWord32); | 2349 var_result(this, MachineRepresentation::kWord32); |
(...skipping 6068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8402 Bind(&if_notequal); | 8418 Bind(&if_notequal); |
8403 { | 8419 { |
8404 result.Bind(BooleanConstant(mode == kNegateResult)); | 8420 result.Bind(BooleanConstant(mode == kNegateResult)); |
8405 Goto(&end); | 8421 Goto(&end); |
8406 } | 8422 } |
8407 | 8423 |
8408 Bind(&end); | 8424 Bind(&end); |
8409 return result.value(); | 8425 return result.value(); |
8410 } | 8426 } |
8411 | 8427 |
8428 // ECMA#sec-samevalue | |
8429 // This algorithm differs from the Strict Equality Comparison Algorithm in its | |
8430 // treatment of signed zeroes and NaNs. | |
8431 compiler::Node* CodeStubAssembler::SameValue(compiler::Node* lhs, | |
8432 compiler::Node* rhs, | |
8433 compiler::Node* context) { | |
8434 Variable var_result(this, MachineType::PointerRepresentation()); | |
8435 Label strict_equal(this), out(this); | |
8436 | |
8437 Node* const int_false = IntPtrConstant(0); | |
8438 Node* const int_true = IntPtrConstant(1); | |
8439 | |
8440 Label if_equal(this), if_notequal(this); | |
8441 Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal); | |
8442 | |
8443 Bind(&if_equal); | |
8444 { | |
8445 // This covers the case when {lhs} == {rhs}. We can simply return true | |
8446 // because SameValue considers two NaNs to be equal. | |
8447 | |
8448 var_result.Bind(int_true); | |
8449 Goto(&out); | |
8450 } | |
8451 | |
8452 Bind(&if_notequal); | |
8453 { | |
8454 // This covers the case when {lhs} != {rhs}. We only handle numbers here | |
8455 // and defer to StrictEqual for the rest. | |
8456 | |
8457 Node* const lhs_float = TryTaggedToFloat64(lhs, &strict_equal); | |
8458 Node* const rhs_float = TryTaggedToFloat64(rhs, &strict_equal); | |
8459 | |
8460 Label if_lhsisnan(this), if_lhsnotnan(this); | |
8461 BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan); | |
8462 | |
8463 Bind(&if_lhsisnan); | |
8464 { | |
8465 // Return true iff {rhs} is NaN. | |
8466 | |
8467 Node* const result = | |
8468 Select(Float64Equal(rhs_float, rhs_float), int_false, int_true); | |
Igor Sheludko
2016/11/11 16:13:21
Select requires also the representation of a resul
jgruber
2016/11/13 13:00:09
Will fix.
jgruber
2016/11/15 10:02:29
Done.
| |
8469 var_result.Bind(result); | |
8470 Goto(&out); | |
8471 } | |
8472 | |
8473 Bind(&if_lhsnotnan); | |
8474 { | |
8475 Label if_floatisequal(this), if_floatnotequal(this); | |
8476 Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal, | |
8477 &if_floatnotequal); | |
8478 | |
8479 Bind(&if_floatisequal); | |
8480 { | |
8481 // We still need to handle the case when {lhs} and {rhs} are -0.0 and | |
8482 // 0.0 (or vice versa). Compare the high word to | |
8483 // distinguish between the two. | |
8484 | |
8485 Node* const lhs_hi_word = Float64ExtractHighWord32(lhs_float); | |
8486 Node* const rhs_hi_word = Float64ExtractHighWord32(rhs_float); | |
8487 | |
8488 // If x is +0 and y is -0, return false. | |
8489 // If x is -0 and y is +0, return false. | |
8490 | |
8491 Node* const result = Word32Equal(lhs_hi_word, rhs_hi_word); | |
8492 var_result.Bind(result); | |
8493 Goto(&out); | |
8494 } | |
8495 | |
8496 Bind(&if_floatnotequal); | |
8497 { | |
8498 var_result.Bind(int_false); | |
8499 Goto(&out); | |
8500 } | |
8501 } | |
8502 } | |
8503 | |
8504 Bind(&strict_equal); | |
8505 { | |
8506 Node* const is_equal = StrictEqual(kDontNegateResult, lhs, rhs, context); | |
8507 Node* const result = WordEqual(is_equal, TrueConstant()); | |
8508 var_result.Bind(result); | |
8509 Goto(&out); | |
8510 } | |
8511 | |
8512 Bind(&out); | |
8513 return var_result.value(); | |
8514 } | |
8515 | |
8412 compiler::Node* CodeStubAssembler::ForInFilter(compiler::Node* key, | 8516 compiler::Node* CodeStubAssembler::ForInFilter(compiler::Node* key, |
8413 compiler::Node* object, | 8517 compiler::Node* object, |
8414 compiler::Node* context) { | 8518 compiler::Node* context) { |
8415 Label return_undefined(this, Label::kDeferred), return_to_name(this), | 8519 Label return_undefined(this, Label::kDeferred), return_to_name(this), |
8416 end(this); | 8520 end(this); |
8417 | 8521 |
8418 Variable var_result(this, MachineRepresentation::kTagged); | 8522 Variable var_result(this, MachineRepresentation::kTagged); |
8419 | 8523 |
8420 Node* has_property = | 8524 Node* has_property = |
8421 HasProperty(object, key, context, Runtime::kForInHasProperty); | 8525 HasProperty(object, key, context, Runtime::kForInHasProperty); |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8910 } | 9014 } |
8911 | 9015 |
8912 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 9016 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
8913 assembler_->PopAndReturn( | 9017 assembler_->PopAndReturn( |
8914 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 9018 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
8915 value); | 9019 value); |
8916 } | 9020 } |
8917 | 9021 |
8918 } // namespace internal | 9022 } // namespace internal |
8919 } // namespace v8 | 9023 } // namespace v8 |
OLD | NEW |