Chromium Code Reviews| 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 | 4 |
| 5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
| 6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
| 7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
| 8 #include "src/frames.h" | 8 #include "src/frames.h" |
| 9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
| 10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
| (...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2353 Bind(&runtime); | 2353 Bind(&runtime); |
| 2354 { | 2354 { |
| 2355 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); | 2355 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); |
| 2356 Goto(&end); | 2356 Goto(&end); |
| 2357 } | 2357 } |
| 2358 | 2358 |
| 2359 Bind(&end); | 2359 Bind(&end); |
| 2360 return var_result.value(); | 2360 return var_result.value(); |
| 2361 } | 2361 } |
| 2362 | 2362 |
| 2363 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { | |
| 2364 // Assert input is a HeapObject (not smi or heap number) | |
| 2365 Assert(Word32BinaryNot(WordIsSmi(input))); | |
| 2366 Assert( | |
| 2367 Word32NotEqual(LoadInstanceType(input), Int32Constant(HEAP_NUMBER_TYPE))); | |
|
Igor Sheludko
2016/09/09 11:33:15
How about doing a map check here?
| |
| 2368 | |
| 2369 // We might need to loop once here due to ToPrimitive conversions. | |
| 2370 Variable var_input(this, MachineRepresentation::kTagged); | |
| 2371 Variable var_result(this, MachineRepresentation::kTagged); | |
| 2372 Label loop(this, &var_input); | |
| 2373 Label end(this); | |
| 2374 var_input.Bind(input); | |
| 2375 Goto(&loop); | |
| 2376 Bind(&loop); | |
| 2377 { | |
| 2378 // Load the current {input} value (known to be a HeapObject). | |
| 2379 Node* input = var_input.value(); | |
| 2380 | |
| 2381 // Dispatch on the {input} instance type. | |
| 2382 Node* input_instance_type = LoadInstanceType(input); | |
| 2383 Label if_inputisstring(this), if_inputisoddball(this), | |
| 2384 if_inputisreceiver(this, Label::kDeferred), | |
| 2385 if_inputisother(this, Label::kDeferred); | |
| 2386 GotoIf( | |
| 2387 Int32LessThan(input_instance_type, Int32Constant(FIRST_NONSTRING_TYPE)), | |
| 2388 &if_inputisstring); | |
| 2389 GotoIf(Word32Equal(input_instance_type, Int32Constant(ODDBALL_TYPE)), | |
| 2390 &if_inputisoddball); | |
| 2391 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | |
| 2392 Branch(Int32GreaterThanOrEqual(input_instance_type, | |
| 2393 Int32Constant(FIRST_JS_RECEIVER_TYPE)), | |
| 2394 &if_inputisreceiver, &if_inputisother); | |
| 2395 | |
| 2396 Bind(&if_inputisstring); | |
| 2397 { | |
| 2398 // The {input} is a String, use the fast stub to convert it to a Number. | |
| 2399 var_result.Bind(StringToNumber(context, input)); | |
| 2400 Goto(&end); | |
| 2401 } | |
| 2402 | |
| 2403 Bind(&if_inputisoddball); | |
| 2404 { | |
| 2405 // The {input} is an Oddball, we just need to load the Number value of it. | |
| 2406 var_result.Bind(LoadObjectField(input, Oddball::kToNumberOffset)); | |
| 2407 Goto(&end); | |
| 2408 } | |
| 2409 | |
| 2410 Bind(&if_inputisreceiver); | |
| 2411 { | |
| 2412 // The {input} is a JSReceiver, we need to convert it to a Primitive first | |
| 2413 // using the ToPrimitive type conversion, preferably yielding a Number. | |
| 2414 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | |
| 2415 isolate(), ToPrimitiveHint::kNumber); | |
| 2416 Node* result = CallStub(callable, context, input); | |
| 2417 | |
| 2418 // Check if the {result} is already a Number. | |
| 2419 Label if_resultisnumber(this), if_resultisnotnumber(this); | |
| 2420 GotoIf(WordIsSmi(result), &if_resultisnumber); | |
| 2421 Node* result_map = LoadMap(result); | |
| 2422 Branch(WordEqual(result_map, HeapNumberMapConstant()), &if_resultisnumber, | |
| 2423 &if_resultisnotnumber); | |
| 2424 | |
| 2425 Bind(&if_resultisnumber); | |
| 2426 { | |
| 2427 // The ToPrimitive conversion already gave us a Number, so we're done. | |
| 2428 var_result.Bind(result); | |
| 2429 Goto(&end); | |
| 2430 } | |
| 2431 | |
| 2432 Bind(&if_resultisnotnumber); | |
| 2433 { | |
| 2434 // We now have a Primitive {result}, but it's not yet a Number. | |
| 2435 var_input.Bind(result); | |
| 2436 Goto(&loop); | |
| 2437 } | |
| 2438 } | |
| 2439 | |
| 2440 Bind(&if_inputisother); | |
| 2441 { | |
| 2442 // The {input} is something else (i.e. Symbol or Simd128Value), let the | |
| 2443 // runtime figure out the correct exception. | |
| 2444 // Note: We cannot tail call to the runtime here, as js-to-wasm | |
| 2445 // trampolines also use this code currently, and they declare all | |
| 2446 // outgoing parameters as untagged, while we would push a tagged | |
| 2447 // object here. | |
| 2448 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); | |
| 2449 Goto(&end); | |
| 2450 } | |
| 2451 } | |
| 2452 | |
| 2453 Bind(&end); | |
| 2454 return var_result.value(); | |
| 2455 } | |
| 2456 | |
| 2457 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { | |
| 2458 Variable var_result(this, MachineRepresentation::kTagged); | |
| 2459 Label end(this); | |
| 2460 | |
| 2461 Label not_smi(this, Label::kDeferred); | |
| 2462 GotoUnless(WordIsSmi(input), ¬_smi); | |
| 2463 var_result.Bind(input); | |
| 2464 Goto(&end); | |
| 2465 | |
| 2466 Bind(¬_smi); | |
| 2467 { | |
| 2468 Label not_heap_number(this, Label::kDeferred); | |
| 2469 Node* input_instance_type = LoadInstanceType(input); | |
| 2470 GotoIf(Word32NotEqual(input_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), | |
|
Igor Sheludko
2016/09/09 11:33:15
While we are here, how about doing a map check ins
| |
| 2471 ¬_heap_number); | |
| 2472 | |
| 2473 var_result.Bind(input); | |
| 2474 Goto(&end); | |
| 2475 | |
| 2476 Bind(¬_heap_number); | |
| 2477 { | |
| 2478 var_result.Bind(NonNumberToNumber(context, input)); | |
| 2479 Goto(&end); | |
| 2480 } | |
| 2481 } | |
| 2482 | |
| 2483 Bind(&end); | |
| 2484 return var_result.value(); | |
| 2485 } | |
| 2486 | |
| 2363 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, | 2487 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, |
| 2364 uint32_t mask) { | 2488 uint32_t mask) { |
| 2365 return Word32Shr(Word32And(word32, Int32Constant(mask)), | 2489 return Word32Shr(Word32And(word32, Int32Constant(mask)), |
| 2366 static_cast<int>(shift)); | 2490 static_cast<int>(shift)); |
| 2367 } | 2491 } |
| 2368 | 2492 |
| 2369 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { | 2493 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { |
| 2370 if (FLAG_native_code_counters && counter->Enabled()) { | 2494 if (FLAG_native_code_counters && counter->Enabled()) { |
| 2371 Node* counter_address = ExternalConstant(ExternalReference(counter)); | 2495 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
| 2372 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, | 2496 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, |
| (...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4321 Heap::kTheHoleValueRootIndex); | 4445 Heap::kTheHoleValueRootIndex); |
| 4322 | 4446 |
| 4323 // Store the WeakCell in the feedback vector. | 4447 // Store the WeakCell in the feedback vector. |
| 4324 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 4448 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
| 4325 CodeStubAssembler::SMI_PARAMETERS); | 4449 CodeStubAssembler::SMI_PARAMETERS); |
| 4326 return cell; | 4450 return cell; |
| 4327 } | 4451 } |
| 4328 | 4452 |
| 4329 } // namespace internal | 4453 } // namespace internal |
| 4330 } // namespace v8 | 4454 } // namespace v8 |
| OLD | NEW |