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

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
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 bool HasNumberValue() const { return has_double_value_; }
2504 int32_t NumberValueAsInteger32() const { 2522 int32_t NumberValueAsInteger32() const {
2505 ASSERT(HasNumberValue()); 2523 ASSERT(HasNumberValue());
2506 if (has_int32_value_) return int32_value_; 2524 // Irrespective of whether a numeric HConstant can be safely
2507 return DoubleToInt32(double_value_); 2525 // represented as an int32, we store the (in some cases lossy)
2526 // representation of the number in int32_value_.
2527 return int32_value_;
2508 } 2528 }
2509 bool HasStringValue() const { return handle_->IsString(); }
2510 2529
2511 bool ToBoolean() const; 2530 bool ToBoolean();
2512 2531
2513 virtual intptr_t Hashcode() { 2532 virtual intptr_t Hashcode() {
2514 ASSERT(!HEAP->allow_allocation(false)); 2533 ASSERT(!HEAP->allow_allocation(false));
2515 intptr_t hash = reinterpret_cast<intptr_t>(*handle()); 2534 intptr_t hash;
2516 // Prevent smis from having fewer hash values when truncated to 2535
2517 // the least significant bits. 2536 if (has_int32_value_) {
2518 const int kShiftSize = kSmiShiftSize + kSmiTagSize; 2537 hash = static_cast<intptr_t>(int32_value_);
2519 STATIC_ASSERT(kShiftSize != 0); 2538 } else if (has_double_value_) {
2520 return hash ^ (hash >> kShiftSize); 2539 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
2540 } else {
2541 ASSERT(!handle_.is_null());
2542 hash = reinterpret_cast<intptr_t>(*handle_);
2543 }
2544
2545 return hash;
2521 } 2546 }
2522 2547
2523 #ifdef DEBUG 2548 #ifdef DEBUG
2524 virtual void Verify() { } 2549 virtual void Verify() { }
2525 #endif 2550 #endif
2526 2551
2527 DECLARE_CONCRETE_INSTRUCTION(Constant) 2552 DECLARE_CONCRETE_INSTRUCTION(Constant)
2528 2553
2529 protected: 2554 protected:
2530 virtual Range* InferRange(Zone* zone); 2555 virtual Range* InferRange(Zone* zone);
2531 2556
2532 virtual bool DataEquals(HValue* other) { 2557 virtual bool DataEquals(HValue* other) {
2533 HConstant* other_constant = HConstant::cast(other); 2558 HConstant* other_constant = HConstant::cast(other);
2534 return handle().is_identical_to(other_constant->handle()); 2559 if (has_int32_value_) {
2560 return other_constant->has_int32_value_ &&
2561 int32_value_ == other_constant->int32_value_;
2562 } else if (has_double_value_) {
2563 return other_constant->has_double_value_ &&
2564 BitCast<int64_t>(double_value_) ==
2565 BitCast<int64_t>(other_constant->double_value_);
2566 } else {
2567 ASSERT(!handle_.is_null());
2568 return !other_constant->handle_.is_null() &&
2569 *handle_ == *other_constant->handle_;
2570 }
2535 } 2571 }
2536 2572
2537 private: 2573 private:
2574 // If this is a numerical constant, handle_ either points to to the
2575 // HeapObject the constant originated from or is null. If the
2576 // constant is non-numeric, handle_ always points to a valid
2577 // constant HeapObject.
2538 Handle<Object> handle_; 2578 Handle<Object> handle_;
2539 2579
2540 // The following two values represent the int32 and the double value of the 2580 // We store the HConstant in the most specific form safely possible.
2541 // given constant if there is a lossless conversion between the constant 2581 // The two flags, has_int32_value_ and has_double_value_ tell us if
2542 // and the specific representation. 2582 // int32_value_ and double_value_ hold valid, safe representations
2583 // of the constant. has_int32_value_ implies has_double_value_ but
2584 // not the converse.
2543 bool has_int32_value_ : 1; 2585 bool has_int32_value_ : 1;
2544 bool has_double_value_ : 1; 2586 bool has_double_value_ : 1;
2545 int32_t int32_value_; 2587 int32_t int32_value_;
2546 double double_value_; 2588 double double_value_;
2547 }; 2589 };
2548 2590
2549 2591
2550 class HBinaryOperation: public HTemplateInstruction<3> { 2592 class HBinaryOperation: public HTemplateInstruction<3> {
2551 public: 2593 public:
2552 HBinaryOperation(HValue* context, HValue* left, HValue* right) { 2594 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
(...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5103 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5145 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5104 }; 5146 };
5105 5147
5106 5148
5107 #undef DECLARE_INSTRUCTION 5149 #undef DECLARE_INSTRUCTION
5108 #undef DECLARE_CONCRETE_INSTRUCTION 5150 #undef DECLARE_CONCRETE_INSTRUCTION
5109 5151
5110 } } // namespace v8::internal 5152 } } // namespace v8::internal
5111 5153
5112 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5154 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698