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

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 integer_value, Representation r, Handle<Object> handle);
2457 HConstant(double double_value, Representation r, Handle<Object> handle);
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
2500 bool IsTagged() {
2501 ASSERT(has_int32_value_ || has_double_value_ || !handle_.is_null());
2502 return !(has_int32_value_ || has_double_value_);
2503 }
2504
2478 virtual bool IsConvertibleToInteger() const { 2505 virtual bool IsConvertibleToInteger() const {
2479 if (handle_->IsSmi()) return true; 2506 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 } 2507 }
2485 2508
2486 virtual bool EmitAtUses() { return !representation().IsDouble(); } 2509 virtual bool EmitAtUses() { return !representation().IsDouble(); }
2487 virtual HValue* Canonicalize(); 2510 virtual HValue* Canonicalize();
2488 virtual void PrintDataTo(StringStream* stream); 2511 virtual void PrintDataTo(StringStream* stream);
2489 virtual HType CalculateInferredType(); 2512 virtual HType CalculateInferredType();
2490 bool IsInteger() const { return handle_->IsSmi(); } 2513 bool IsInteger() { return handle()->IsSmi(); }
2491 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 2514 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
2492 HConstant* CopyToTruncatedInt32(Zone* zone) const; 2515 HConstant* CopyToTruncatedInt32(Zone* zone) const;
2493 bool HasInteger32Value() const { return has_int32_value_; } 2516 bool HasInteger32Value() const { return has_int32_value_; }
2494 int32_t Integer32Value() const { 2517 int32_t Integer32Value() const {
2495 ASSERT(HasInteger32Value()); 2518 ASSERT(HasInteger32Value());
2496 return int32_value_; 2519 return int32_value_;
2497 } 2520 }
2498 bool HasDoubleValue() const { return has_double_value_; } 2521 bool HasDoubleValue() const { return has_double_value_; }
2499 double DoubleValue() const { 2522 double DoubleValue() const {
2500 ASSERT(HasDoubleValue()); 2523 ASSERT(HasDoubleValue());
2501 return double_value_; 2524 return double_value_;
2502 } 2525 }
2503 bool HasNumberValue() const { return has_int32_value_ || has_double_value_; } 2526 bool HasNumberValue() const { return has_double_value_; }
2504 int32_t NumberValueAsInteger32() const { 2527 int32_t NumberValueAsInteger32() const {
2505 ASSERT(HasNumberValue()); 2528 ASSERT(HasNumberValue());
2506 if (has_int32_value_) return int32_value_; 2529 return int32_value_;
2507 return DoubleToInt32(double_value_);
2508 } 2530 }
2509 bool HasStringValue() const { return handle_->IsString(); }
2510 2531
2511 bool ToBoolean() const; 2532 bool ToBoolean();
2512 2533
2513 virtual intptr_t Hashcode() { 2534 virtual intptr_t Hashcode() {
2514 ASSERT(!HEAP->allow_allocation(false)); 2535 ASSERT(!HEAP->allow_allocation(false));
2515 intptr_t hash = reinterpret_cast<intptr_t>(*handle()); 2536 intptr_t hash;
2516 // Prevent smis from having fewer hash values when truncated to 2537
2517 // the least significant bits. 2538 if (has_int32_value_) {
2518 const int kShiftSize = kSmiShiftSize + kSmiTagSize; 2539 hash = static_cast<intptr_t>(int32_value_);
2519 STATIC_ASSERT(kShiftSize != 0); 2540 // Prevent smis from having fewer hash values when truncated to
2520 return hash ^ (hash >> kShiftSize); 2541 // the least significant bits.
2542 const int kShiftSize = kSmiShiftSize + kSmiTagSize;
2543 STATIC_ASSERT(kShiftSize != 0);
2544 hash = hash ^ (hash >> kShiftSize);
2545 } else if (has_double_value_) {
2546 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
2547 } else {
2548 ASSERT(!handle_.is_null());
2549 hash = reinterpret_cast<intptr_t>(*handle_);
2550 }
2551
2552 return hash;
2521 } 2553 }
2522 2554
2523 #ifdef DEBUG 2555 #ifdef DEBUG
2524 virtual void Verify() { } 2556 virtual void Verify() { }
2525 #endif 2557 #endif
2526 2558
2527 DECLARE_CONCRETE_INSTRUCTION(Constant) 2559 DECLARE_CONCRETE_INSTRUCTION(Constant)
2528 2560
2529 protected: 2561 protected:
2530 virtual Range* InferRange(Zone* zone); 2562 virtual Range* InferRange(Zone* zone);
2531 2563
2532 virtual bool DataEquals(HValue* other) { 2564 virtual bool DataEquals(HValue* other) {
2533 HConstant* other_constant = HConstant::cast(other); 2565 HConstant* other_constant = HConstant::cast(other);
2534 return handle().is_identical_to(other_constant->handle()); 2566 if (has_int32_value_) {
2567 return other_constant->has_int32_value_ &&
2568 int32_value_ == other_constant->int32_value_;
2569 } else if (has_double_value_) {
2570 return other_constant->has_double_value_ &&
2571 BitCast<int64_t>(double_value_) ==
2572 BitCast<int64_t>(other_constant->double_value_);
2573 } else {
2574 ASSERT(!handle_.is_null());
2575 return !other_constant->handle_.is_null() &&
2576 *handle_ == *other_constant->handle_;
2577 }
2535 } 2578 }
2536 2579
2537 private: 2580 private:
2581 // We store the HConstant in the most specific form safely possible.
2582 // The two flags, has_int32_value_ and has_double_value_ tell us if
2583 // int32_value_ and double_value_ hold valid, safe representations
2584 // of the constant. has_int32_value_ implies has_double_value_ but
2585 // not the converse.
2586
2587 // If this is a numerical constant, handle_ either points to to the
2588 // HeapObject the constant originated from or is null. If the
2589 // constant is non-numeric, handle_ always points to a valid
2590 // constant HeapObject.
2591
2538 Handle<Object> handle_; 2592 Handle<Object> handle_;
2539 2593
2540 // The following two values represent the int32 and the double value of the
2541 // given constant if there is a lossless conversion between the constant
2542 // and the specific representation.
2543 bool has_int32_value_ : 1; 2594 bool has_int32_value_ : 1;
2544 bool has_double_value_ : 1; 2595 bool has_double_value_ : 1;
2545 int32_t int32_value_; 2596 int32_t int32_value_;
2546 double double_value_; 2597 double double_value_;
2547 }; 2598 };
2548 2599
2549 2600
2550 class HBinaryOperation: public HTemplateInstruction<3> { 2601 class HBinaryOperation: public HTemplateInstruction<3> {
2551 public: 2602 public:
2552 HBinaryOperation(HValue* context, HValue* left, HValue* right) { 2603 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5103 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5154 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5104 }; 5155 };
5105 5156
5106 5157
5107 #undef DECLARE_INSTRUCTION 5158 #undef DECLARE_INSTRUCTION
5108 #undef DECLARE_CONCRETE_INSTRUCTION 5159 #undef DECLARE_CONCRETE_INSTRUCTION
5109 5160
5110 } } // namespace v8::internal 5161 } } // namespace v8::internal
5111 5162
5112 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5163 #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