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

Side by Side Diff: src/hydrogen-instructions.h

Issue 10544196: Defer creating Handles for HConstants to the code generation phase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review. Created 8 years, 5 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 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 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 return Representation::None(); 2446 return Representation::None();
2447 } 2447 }
2448 2448
2449 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) 2449 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
2450 }; 2450 };
2451 2451
2452 2452
2453 class HConstant: public HTemplateInstruction<0> { 2453 class HConstant: public HTemplateInstruction<0> {
2454 public: 2454 public:
2455 HConstant(Handle<Object> handle, Representation r); 2455 HConstant(Handle<Object> handle, Representation r);
2456 HConstant(int32_t value, Representation r);
2457 HConstant(double value, Representation r);
2456 2458
2457 Handle<Object> handle() const { return handle_; } 2459 Handle<Object> handle() {
2460 if (handle_.is_null()) {
2461 handle_ = FACTORY->NewNumber(double_value_, TENURED);
2462 }
2463 ASSERT(has_int32_value_ || !handle_->IsSmi());
2464 return handle_;
2465 }
2458 2466
2459 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } 2467 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
2460 2468
2461 bool ImmortalImmovable() const { 2469 bool ImmortalImmovable() const {
2470 if (has_int32_value_) {
2471 return false;
2472 }
2473 if (has_double_value_) {
2474 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
2475 isnan(double_value_)) {
2476 return true;
2477 }
2478 return false;
2479 }
2480
2481 ASSERT(!handle_.is_null());
2462 Heap* heap = HEAP; 2482 Heap* heap = HEAP;
2483 // We should have handled minus_zero_value and nan_value in the
2484 // has_double_value_ clause above.
2485 ASSERT(*handle_ != heap->minus_zero_value());
2486 ASSERT(*handle_ != heap->nan_value());
2463 if (*handle_ == heap->undefined_value()) return true; 2487 if (*handle_ == heap->undefined_value()) return true;
2464 if (*handle_ == heap->null_value()) return true; 2488 if (*handle_ == heap->null_value()) return true;
2465 if (*handle_ == heap->true_value()) return true; 2489 if (*handle_ == heap->true_value()) return true;
2466 if (*handle_ == heap->false_value()) return true; 2490 if (*handle_ == heap->false_value()) return true;
2467 if (*handle_ == heap->the_hole_value()) return true; 2491 if (*handle_ == heap->the_hole_value()) return true;
2468 if (*handle_ == heap->minus_zero_value()) return true;
2469 if (*handle_ == heap->nan_value()) return true;
2470 if (*handle_ == heap->empty_string()) return true; 2492 if (*handle_ == heap->empty_string()) return true;
2471 return false; 2493 return false;
2472 } 2494 }
2473 2495
2474 virtual Representation RequiredInputRepresentation(int index) { 2496 virtual Representation RequiredInputRepresentation(int index) {
2475 return Representation::None(); 2497 return Representation::None();
2476 } 2498 }
2477 2499
2478 virtual bool IsConvertibleToInteger() const { 2500 virtual bool IsConvertibleToInteger() const {
2479 if (handle_->IsSmi()) return true; 2501 return has_int32_value_;
2480 if (handle_->IsHeapNumber() &&
2481 (HeapNumber::cast(*handle_)->value() ==
2482 static_cast<double>(NumberToInt32(*handle_)))) return true;
2483 return false;
2484 } 2502 }
2485 2503
2486 virtual bool EmitAtUses() { return !representation().IsDouble(); } 2504 virtual bool EmitAtUses() { return !representation().IsDouble(); }
2487 virtual HValue* Canonicalize(); 2505 virtual HValue* Canonicalize();
2488 virtual void PrintDataTo(StringStream* stream); 2506 virtual void PrintDataTo(StringStream* stream);
2489 virtual HType CalculateInferredType(); 2507 virtual HType CalculateInferredType();
2490 bool IsInteger() const { return handle_->IsSmi(); } 2508 bool IsInteger() { return handle()->IsSmi(); }
2491 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 2509 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
2492 HConstant* CopyToTruncatedInt32(Zone* zone) const; 2510 HConstant* CopyToTruncatedInt32(Zone* zone) const;
2493 bool HasInteger32Value() const { return has_int32_value_; } 2511 bool HasInteger32Value() const { return has_int32_value_; }
2494 int32_t Integer32Value() const { 2512 int32_t Integer32Value() const {
2495 ASSERT(HasInteger32Value()); 2513 ASSERT(HasInteger32Value());
2496 return int32_value_; 2514 return int32_value_;
2497 } 2515 }
2498 bool HasDoubleValue() const { return has_double_value_; } 2516 bool HasDoubleValue() const { return has_double_value_; }
2499 double DoubleValue() const { 2517 double DoubleValue() const {
2500 ASSERT(HasDoubleValue()); 2518 ASSERT(HasDoubleValue());
2501 return double_value_; 2519 return double_value_;
2502 } 2520 }
2503 bool HasNumberValue() const { return has_int32_value_ || has_double_value_; } 2521
2522 // has_double_value_ can be true either if this HConstant represents
2523 // a double constant or if it represents an int32 constant. In
2524 // either case the HConstant has a numeric value.
Michael Starzinger 2012/07/11 14:19:22 Drop this block of comments and the empty newline!
2525 bool HasNumberValue() const { return has_double_value_; }
2504 int32_t NumberValueAsInteger32() const { 2526 int32_t NumberValueAsInteger32() const {
2505 ASSERT(HasNumberValue()); 2527 ASSERT(HasNumberValue());
2506 if (has_int32_value_) return int32_value_; 2528 // Irrespective of whether a numeric HConstant can be safely
2507 return DoubleToInt32(double_value_); 2529 // represented as an int32, we store the (in some cases lossy)
2530 // representation of the number in int32_value_.
2531 return int32_value_;
2508 } 2532 }
2509 bool HasStringValue() const { return handle_->IsString(); }
2510 2533
2511 bool ToBoolean() const; 2534 bool ToBoolean();
2512 2535
2513 virtual intptr_t Hashcode() { 2536 virtual intptr_t Hashcode() {
2514 ASSERT(!HEAP->allow_allocation(false)); 2537 ASSERT(!HEAP->allow_allocation(false));
2515 intptr_t hash = reinterpret_cast<intptr_t>(*handle()); 2538 intptr_t hash;
2516 // Prevent smis from having fewer hash values when truncated to 2539
2517 // the least significant bits. 2540 if (has_int32_value_) {
2518 const int kShiftSize = kSmiShiftSize + kSmiTagSize; 2541 hash = static_cast<intptr_t>(int32_value_);
2519 STATIC_ASSERT(kShiftSize != 0); 2542 } else if (has_double_value_) {
2520 return hash ^ (hash >> kShiftSize); 2543 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
2544 } else {
2545 ASSERT(!handle_.is_null());
2546 hash = reinterpret_cast<intptr_t>(*handle_);
2547 }
2548
2549 return hash;
2521 } 2550 }
2522 2551
2523 #ifdef DEBUG 2552 #ifdef DEBUG
2524 virtual void Verify() { } 2553 virtual void Verify() { }
2525 #endif 2554 #endif
2526 2555
2527 DECLARE_CONCRETE_INSTRUCTION(Constant) 2556 DECLARE_CONCRETE_INSTRUCTION(Constant)
2528 2557
2529 protected: 2558 protected:
2530 virtual Range* InferRange(Zone* zone); 2559 virtual Range* InferRange(Zone* zone);
2531 2560
2532 virtual bool DataEquals(HValue* other) { 2561 virtual bool DataEquals(HValue* other) {
2533 HConstant* other_constant = HConstant::cast(other); 2562 HConstant* other_constant = HConstant::cast(other);
2534 return handle().is_identical_to(other_constant->handle()); 2563 if (has_int32_value_) {
2564 return other_constant->has_int32_value_ &&
2565 int32_value_ == other_constant->int32_value_;
2566 } else if (has_double_value_) {
2567 return other_constant->has_double_value_ &&
2568 BitCast<int64_t>(double_value_) ==
2569 BitCast<int64_t>(other_constant->double_value_);
2570 } else {
2571 ASSERT(!handle_.is_null());
2572 return !other_constant->handle_.is_null() &&
2573 *handle_ == *other_constant->handle_;
2574 }
2535 } 2575 }
2536 2576
2537 private: 2577 private:
2578 // If this is a numerical constant, handle_ either points to to the
2579 // HeapObject the constant originated from or is null. If the
2580 // constant is non-numeric, handle_ always points to a valid
2581 // constant HeapObject.
2538 Handle<Object> handle_; 2582 Handle<Object> handle_;
2539 2583
2540 // The following two values represent the int32 and the double value of the 2584 // We store the HConstant in the most specific form safely possible.
2541 // given constant if there is a lossless conversion between the constant 2585 // The two flags, has_int32_value_ and has_double_value_ tell us if
2542 // and the specific representation. 2586 // int32_value_ and double_value_ hold valid, safe representations
2587 // of the constant. has_int32_value_ implies has_double_value_ but
2588 // not the converse.
2543 bool has_int32_value_ : 1; 2589 bool has_int32_value_ : 1;
2544 bool has_double_value_ : 1; 2590 bool has_double_value_ : 1;
2545 int32_t int32_value_; 2591 int32_t int32_value_;
2546 double double_value_; 2592 double double_value_;
2547 }; 2593 };
2548 2594
2549 2595
2550 class HBinaryOperation: public HTemplateInstruction<3> { 2596 class HBinaryOperation: public HTemplateInstruction<3> {
2551 public: 2597 public:
2552 HBinaryOperation(HValue* context, HValue* left, HValue* right) { 2598 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5103 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5149 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5104 }; 5150 };
5105 5151
5106 5152
5107 #undef DECLARE_INSTRUCTION 5153 #undef DECLARE_INSTRUCTION
5108 #undef DECLARE_CONCRETE_INSTRUCTION 5154 #undef DECLARE_CONCRETE_INSTRUCTION
5109 5155
5110 } } // namespace v8::internal 5156 } } // namespace v8::internal
5111 5157
5112 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5158 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698