OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2356 | 2356 |
2357 | 2357 |
2358 static bool IsInteger32(double value) { | 2358 static bool IsInteger32(double value) { |
2359 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 2359 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
2360 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 2360 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
2361 } | 2361 } |
2362 | 2362 |
2363 | 2363 |
2364 HConstant::HConstant(Handle<Object> handle, Representation r) | 2364 HConstant::HConstant(Handle<Object> handle, Representation r) |
2365 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), | 2365 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), |
2366 handle_(handle), | 2366 object_(Unique<Object>::CreateUninitialized(handle)), |
2367 unique_id_(), | |
2368 has_smi_value_(false), | 2367 has_smi_value_(false), |
2369 has_int32_value_(false), | 2368 has_int32_value_(false), |
2370 has_double_value_(false), | 2369 has_double_value_(false), |
2371 has_external_reference_value_(false), | 2370 has_external_reference_value_(false), |
2372 is_internalized_string_(false), | 2371 is_internalized_string_(false), |
2373 is_not_in_new_space_(true), | 2372 is_not_in_new_space_(true), |
2374 is_cell_(false), | 2373 is_cell_(false), |
2375 boolean_value_(handle->BooleanValue()) { | 2374 boolean_value_(handle->BooleanValue()) { |
2376 if (handle_->IsHeapObject()) { | 2375 if (handle->IsHeapObject()) { |
2377 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); | 2376 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); |
2378 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2377 is_not_in_new_space_ = !heap->InNewSpace(*handle); |
2379 } | 2378 } |
2380 if (handle_->IsNumber()) { | 2379 if (handle->IsNumber()) { |
2381 double n = handle_->Number(); | 2380 double n = handle->Number(); |
2382 has_int32_value_ = IsInteger32(n); | 2381 has_int32_value_ = IsInteger32(n); |
2383 int32_value_ = DoubleToInt32(n); | 2382 int32_value_ = DoubleToInt32(n); |
2384 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2383 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2385 double_value_ = n; | 2384 double_value_ = n; |
2386 has_double_value_ = true; | 2385 has_double_value_ = true; |
2387 } else { | 2386 } else { |
2388 is_internalized_string_ = handle_->IsInternalizedString(); | 2387 is_internalized_string_ = handle->IsInternalizedString(); |
2389 } | 2388 } |
2390 | 2389 |
2391 is_cell_ = !handle_.is_null() && | 2390 is_cell_ = !handle.is_null() && |
2392 (handle_->IsCell() || handle_->IsPropertyCell()); | 2391 (handle->IsCell() || handle->IsPropertyCell()); |
2393 Initialize(r); | 2392 Initialize(r); |
2394 } | 2393 } |
2395 | 2394 |
2396 | 2395 |
2397 HConstant::HConstant(Handle<Object> handle, | 2396 HConstant::HConstant(Unique<Object> unique, |
2398 UniqueValueId unique_id, | |
2399 Representation r, | 2397 Representation r, |
2400 HType type, | 2398 HType type, |
2401 bool is_internalize_string, | 2399 bool is_internalize_string, |
2402 bool is_not_in_new_space, | 2400 bool is_not_in_new_space, |
2403 bool is_cell, | 2401 bool is_cell, |
2404 bool boolean_value) | 2402 bool boolean_value) |
2405 : HTemplateInstruction<0>(type), | 2403 : HTemplateInstruction<0>(type), |
2406 handle_(handle), | 2404 object_(unique), |
2407 unique_id_(unique_id), | |
2408 has_smi_value_(false), | 2405 has_smi_value_(false), |
2409 has_int32_value_(false), | 2406 has_int32_value_(false), |
2410 has_double_value_(false), | 2407 has_double_value_(false), |
2411 has_external_reference_value_(false), | 2408 has_external_reference_value_(false), |
2412 is_internalized_string_(is_internalize_string), | 2409 is_internalized_string_(is_internalize_string), |
2413 is_not_in_new_space_(is_not_in_new_space), | 2410 is_not_in_new_space_(is_not_in_new_space), |
2414 is_cell_(is_cell), | 2411 is_cell_(is_cell), |
2415 boolean_value_(boolean_value) { | 2412 boolean_value_(boolean_value) { |
2416 ASSERT(!handle.is_null()); | 2413 ASSERT(!unique.handle().is_null()); |
2417 ASSERT(!type.IsTaggedNumber()); | 2414 ASSERT(!type.IsTaggedNumber()); |
2418 Initialize(r); | 2415 Initialize(r); |
2419 } | 2416 } |
2420 | 2417 |
2421 | 2418 |
2422 HConstant::HConstant(Handle<Map> handle, | |
2423 UniqueValueId unique_id) | |
2424 : HTemplateInstruction<0>(HType::Tagged()), | |
2425 handle_(handle), | |
2426 unique_id_(unique_id), | |
2427 has_smi_value_(false), | |
2428 has_int32_value_(false), | |
2429 has_double_value_(false), | |
2430 has_external_reference_value_(false), | |
2431 is_internalized_string_(false), | |
2432 is_not_in_new_space_(true), | |
2433 is_cell_(false), | |
2434 boolean_value_(false) { | |
2435 ASSERT(!handle.is_null()); | |
2436 Initialize(Representation::Tagged()); | |
2437 } | |
2438 | |
2439 | |
2440 HConstant::HConstant(int32_t integer_value, | 2419 HConstant::HConstant(int32_t integer_value, |
2441 Representation r, | 2420 Representation r, |
2442 bool is_not_in_new_space, | 2421 bool is_not_in_new_space, |
2443 Handle<Object> optional_handle) | 2422 Unique<Object> object) |
2444 : handle_(optional_handle), | 2423 : object_(object), |
2445 unique_id_(), | |
2446 has_smi_value_(Smi::IsValid(integer_value)), | 2424 has_smi_value_(Smi::IsValid(integer_value)), |
2447 has_int32_value_(true), | 2425 has_int32_value_(true), |
2448 has_double_value_(true), | 2426 has_double_value_(true), |
2449 has_external_reference_value_(false), | 2427 has_external_reference_value_(false), |
2450 is_internalized_string_(false), | 2428 is_internalized_string_(false), |
2451 is_not_in_new_space_(is_not_in_new_space), | 2429 is_not_in_new_space_(is_not_in_new_space), |
2452 is_cell_(false), | 2430 is_cell_(false), |
2453 boolean_value_(integer_value != 0), | 2431 boolean_value_(integer_value != 0), |
2454 int32_value_(integer_value), | 2432 int32_value_(integer_value), |
2455 double_value_(FastI2D(integer_value)) { | 2433 double_value_(FastI2D(integer_value)) { |
2456 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2434 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2457 Initialize(r); | 2435 Initialize(r); |
2458 } | 2436 } |
2459 | 2437 |
2460 | 2438 |
2461 HConstant::HConstant(double double_value, | 2439 HConstant::HConstant(double double_value, |
2462 Representation r, | 2440 Representation r, |
2463 bool is_not_in_new_space, | 2441 bool is_not_in_new_space, |
2464 Handle<Object> optional_handle) | 2442 Unique<Object> object) |
2465 : handle_(optional_handle), | 2443 : object_(object), |
2466 unique_id_(), | |
2467 has_int32_value_(IsInteger32(double_value)), | 2444 has_int32_value_(IsInteger32(double_value)), |
2468 has_double_value_(true), | 2445 has_double_value_(true), |
2469 has_external_reference_value_(false), | 2446 has_external_reference_value_(false), |
2470 is_internalized_string_(false), | 2447 is_internalized_string_(false), |
2471 is_not_in_new_space_(is_not_in_new_space), | 2448 is_not_in_new_space_(is_not_in_new_space), |
2472 is_cell_(false), | 2449 is_cell_(false), |
2473 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2450 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
2474 int32_value_(DoubleToInt32(double_value)), | 2451 int32_value_(DoubleToInt32(double_value)), |
2475 double_value_(double_value) { | 2452 double_value_(double_value) { |
2476 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2453 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2477 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2454 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2478 Initialize(r); | 2455 Initialize(r); |
2479 } | 2456 } |
2480 | 2457 |
2481 | 2458 |
2482 HConstant::HConstant(ExternalReference reference) | 2459 HConstant::HConstant(ExternalReference reference) |
2483 : HTemplateInstruction<0>(HType::None()), | 2460 : HTemplateInstruction<0>(HType::None()), |
| 2461 object_(Unique<Object>(Handle<Object>::null())), |
2484 has_smi_value_(false), | 2462 has_smi_value_(false), |
2485 has_int32_value_(false), | 2463 has_int32_value_(false), |
2486 has_double_value_(false), | 2464 has_double_value_(false), |
2487 has_external_reference_value_(true), | 2465 has_external_reference_value_(true), |
2488 is_internalized_string_(false), | 2466 is_internalized_string_(false), |
2489 is_not_in_new_space_(true), | 2467 is_not_in_new_space_(true), |
2490 is_cell_(false), | 2468 is_cell_(false), |
2491 boolean_value_(true), | 2469 boolean_value_(true), |
2492 external_reference_value_(reference) { | 2470 external_reference_value_(reference) { |
2493 Initialize(Representation::External()); | 2471 Initialize(Representation::External()); |
2494 } | 2472 } |
2495 | 2473 |
2496 | 2474 |
2497 static void PrepareConstant(Handle<Object> object) { | |
2498 if (!object->IsJSObject()) return; | |
2499 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | |
2500 if (!js_object->map()->is_deprecated()) return; | |
2501 JSObject::TryMigrateInstance(js_object); | |
2502 } | |
2503 | |
2504 | |
2505 void HConstant::Initialize(Representation r) { | 2475 void HConstant::Initialize(Representation r) { |
2506 if (r.IsNone()) { | 2476 if (r.IsNone()) { |
2507 if (has_smi_value_ && SmiValuesAre31Bits()) { | 2477 if (has_smi_value_ && SmiValuesAre31Bits()) { |
2508 r = Representation::Smi(); | 2478 r = Representation::Smi(); |
2509 } else if (has_int32_value_) { | 2479 } else if (has_int32_value_) { |
2510 r = Representation::Integer32(); | 2480 r = Representation::Integer32(); |
2511 } else if (has_double_value_) { | 2481 } else if (has_double_value_) { |
2512 r = Representation::Double(); | 2482 r = Representation::Double(); |
2513 } else if (has_external_reference_value_) { | 2483 } else if (has_external_reference_value_) { |
2514 r = Representation::External(); | 2484 r = Representation::External(); |
2515 } else { | 2485 } else { |
2516 PrepareConstant(handle_); | 2486 Handle<Object> object = object_.handle(); |
| 2487 if (object->IsJSObject()) { |
| 2488 // Try to eagerly migrate JSObjects that have deprecated maps. |
| 2489 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 2490 if (js_object->map()->is_deprecated()) { |
| 2491 JSObject::TryMigrateInstance(js_object); |
| 2492 } |
| 2493 } |
2517 r = Representation::Tagged(); | 2494 r = Representation::Tagged(); |
2518 } | 2495 } |
2519 } | 2496 } |
2520 set_representation(r); | 2497 set_representation(r); |
2521 SetFlag(kUseGVN); | 2498 SetFlag(kUseGVN); |
2522 } | 2499 } |
2523 | 2500 |
2524 | 2501 |
2525 bool HConstant::EmitAtUses() { | 2502 bool HConstant::EmitAtUses() { |
2526 ASSERT(IsLinked()); | 2503 ASSERT(IsLinked()); |
2527 if (block()->graph()->has_osr() && | 2504 if (block()->graph()->has_osr() && |
2528 block()->graph()->IsStandardConstant(this)) { | 2505 block()->graph()->IsStandardConstant(this)) { |
2529 return true; | 2506 return true; |
2530 } | 2507 } |
2531 if (UseCount() == 0) return true; | 2508 if (UseCount() == 0) return true; |
2532 if (IsCell()) return false; | 2509 if (IsCell()) return false; |
2533 if (representation().IsDouble()) return false; | 2510 if (representation().IsDouble()) return false; |
2534 return true; | 2511 return true; |
2535 } | 2512 } |
2536 | 2513 |
2537 | 2514 |
2538 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2515 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
2539 if (r.IsSmi() && !has_smi_value_) return NULL; | 2516 if (r.IsSmi() && !has_smi_value_) return NULL; |
2540 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2517 if (r.IsInteger32() && !has_int32_value_) return NULL; |
2541 if (r.IsDouble() && !has_double_value_) return NULL; | 2518 if (r.IsDouble() && !has_double_value_) return NULL; |
2542 if (r.IsExternal() && !has_external_reference_value_) return NULL; | 2519 if (r.IsExternal() && !has_external_reference_value_) return NULL; |
2543 if (has_int32_value_) { | 2520 if (has_int32_value_) { |
2544 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_); | 2521 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_); |
2545 } | 2522 } |
2546 if (has_double_value_) { | 2523 if (has_double_value_) { |
2547 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_); | 2524 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); |
2548 } | 2525 } |
2549 if (has_external_reference_value_) { | 2526 if (has_external_reference_value_) { |
2550 return new(zone) HConstant(external_reference_value_); | 2527 return new(zone) HConstant(external_reference_value_); |
2551 } | 2528 } |
2552 ASSERT(!handle_.is_null()); | 2529 ASSERT(!object_.handle().is_null()); |
2553 return new(zone) HConstant(handle_, | 2530 return new(zone) HConstant(object_, |
2554 unique_id_, | |
2555 r, | 2531 r, |
2556 type_, | 2532 type_, |
2557 is_internalized_string_, | 2533 is_internalized_string_, |
2558 is_not_in_new_space_, | 2534 is_not_in_new_space_, |
2559 is_cell_, | 2535 is_cell_, |
2560 boolean_value_); | 2536 boolean_value_); |
2561 } | 2537 } |
2562 | 2538 |
2563 | 2539 |
2564 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { | 2540 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { |
2565 HConstant* res = NULL; | 2541 HConstant* res = NULL; |
2566 if (has_int32_value_) { | 2542 if (has_int32_value_) { |
2567 res = new(zone) HConstant(int32_value_, | 2543 res = new(zone) HConstant(int32_value_, |
2568 Representation::Integer32(), | 2544 Representation::Integer32(), |
2569 is_not_in_new_space_, | 2545 is_not_in_new_space_, |
2570 handle_); | 2546 object_); |
2571 } else if (has_double_value_) { | 2547 } else if (has_double_value_) { |
2572 res = new(zone) HConstant(DoubleToInt32(double_value_), | 2548 res = new(zone) HConstant(DoubleToInt32(double_value_), |
2573 Representation::Integer32(), | 2549 Representation::Integer32(), |
2574 is_not_in_new_space_, | 2550 is_not_in_new_space_, |
2575 handle_); | 2551 object_); |
2576 } | 2552 } |
2577 return Maybe<HConstant*>(res != NULL, res); | 2553 return Maybe<HConstant*>(res != NULL, res); |
2578 } | 2554 } |
2579 | 2555 |
2580 | 2556 |
2581 Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Zone* zone) { | 2557 Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Zone* zone) { |
2582 HConstant* res = NULL; | 2558 HConstant* res = NULL; |
2583 Handle<Object> handle = this->handle(zone->isolate()); | 2559 Handle<Object> handle = this->handle(zone->isolate()); |
2584 if (handle->IsBoolean()) { | 2560 if (handle->IsBoolean()) { |
2585 res = handle->BooleanValue() ? | 2561 res = handle->BooleanValue() ? |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3432 Zone* zone = block()->zone(); | 3408 Zone* zone = block()->zone(); |
3433 int32_t dominator_size = | 3409 int32_t dominator_size = |
3434 HConstant::cast(dominating_allocate_->size())->GetInteger32Constant(); | 3410 HConstant::cast(dominating_allocate_->size())->GetInteger32Constant(); |
3435 HInstruction* free_space_instr = | 3411 HInstruction* free_space_instr = |
3436 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, | 3412 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, |
3437 dominator_size, type()); | 3413 dominator_size, type()); |
3438 free_space_instr->InsertBefore(this); | 3414 free_space_instr->InsertBefore(this); |
3439 HConstant* filler_map = HConstant::New( | 3415 HConstant* filler_map = HConstant::New( |
3440 zone, | 3416 zone, |
3441 context(), | 3417 context(), |
3442 isolate()->factory()->free_space_map(), | 3418 isolate()->factory()->free_space_map()); |
3443 UniqueValueId::free_space_map(isolate()->heap())); | 3419 filler_map->FinalizeUniqueness(); // TODO(titzer): should be init'd a'ready |
3444 filler_map->InsertAfter(free_space_instr); | 3420 filler_map->InsertAfter(free_space_instr); |
3445 HInstruction* store_map = HStoreNamedField::New(zone, context(), | 3421 HInstruction* store_map = HStoreNamedField::New(zone, context(), |
3446 free_space_instr, HObjectAccess::ForMap(), filler_map); | 3422 free_space_instr, HObjectAccess::ForMap(), filler_map); |
3447 store_map->SetFlag(HValue::kHasNoObservableSideEffects); | 3423 store_map->SetFlag(HValue::kHasNoObservableSideEffects); |
3448 store_map->InsertAfter(filler_map); | 3424 store_map->InsertAfter(filler_map); |
3449 | 3425 |
3450 // We must explicitly force Smi representation here because on x64 we | 3426 // We must explicitly force Smi representation here because on x64 we |
3451 // would otherwise automatically choose int32, but the actual store | 3427 // would otherwise automatically choose int32, but the actual store |
3452 // requires a Smi-tagged value. | 3428 // requires a Smi-tagged value. |
3453 HConstant* filler_size = HConstant::CreateAndInsertAfter( | 3429 HConstant* filler_size = HConstant::CreateAndInsertAfter( |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4223 break; | 4199 break; |
4224 case kExternalMemory: | 4200 case kExternalMemory: |
4225 stream->Add("[external-memory]"); | 4201 stream->Add("[external-memory]"); |
4226 break; | 4202 break; |
4227 } | 4203 } |
4228 | 4204 |
4229 stream->Add("@%d", offset()); | 4205 stream->Add("@%d", offset()); |
4230 } | 4206 } |
4231 | 4207 |
4232 } } // namespace v8::internal | 4208 } } // namespace v8::internal |
OLD | NEW |