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

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: Rebase & cosmetic changes. 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 2433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2444 return Representation::None(); 2444 return Representation::None();
2445 } 2445 }
2446 2446
2447 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject) 2447 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
2448 }; 2448 };
2449 2449
2450 2450
2451 class HConstant: public HTemplateInstruction<0> { 2451 class HConstant: public HTemplateInstruction<0> {
2452 public: 2452 public:
2453 HConstant(Handle<Object> handle, Representation r); 2453 HConstant(Handle<Object> handle, Representation r);
2454 HConstant(int32_t integer_value, Representation r, Handle<Object> handle);
Michael Starzinger 2012/07/09 09:57:09 I think we can get by with just two constructors.
sanjoy 2012/07/09 13:47:37 We need the double-only constructor when folding d
Michael Starzinger 2012/07/09 15:36:22 Yes, but isn't that only called during building of
2455 HConstant(double double_value, Representation r, Handle<Object> handle);
2454 2456
2455 Handle<Object> handle() const { return handle_; } 2457 Handle<Object> handle() const {
2458 ASSERT(!handle_.is_null());
Michael Starzinger 2012/07/09 09:57:09 This change introduces a large amount of complexit
sanjoy 2012/07/09 13:47:37 Fixed. handle() now lazily allocates a Handle.
2459 return handle_;
2460 }
2456 2461
2457 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } 2462 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
2458 2463
2459 bool ImmortalImmovable() const { 2464 bool ImmortalImmovable() const {
2465 if (has_int32_value_) {
2466 return false;
2467 }
2468 if (has_double_value_) {
2469 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
2470 isnan(double_value_)) {
2471 return true;
2472 }
2473 return false;
2474 }
2460 Heap* heap = HEAP; 2475 Heap* heap = HEAP;
2476 // We should have handled minus_zero_value and nan_value in the
2477 // has_double_value_ clause above.
2478 ASSERT(*handle_ != heap->minus_zero_value());
2479 ASSERT(*handle_ != heap->nan_value());
2461 if (*handle_ == heap->undefined_value()) return true; 2480 if (*handle_ == heap->undefined_value()) return true;
2462 if (*handle_ == heap->null_value()) return true; 2481 if (*handle_ == heap->null_value()) return true;
2463 if (*handle_ == heap->true_value()) return true; 2482 if (*handle_ == heap->true_value()) return true;
2464 if (*handle_ == heap->false_value()) return true; 2483 if (*handle_ == heap->false_value()) return true;
2465 if (*handle_ == heap->the_hole_value()) return true; 2484 if (*handle_ == heap->the_hole_value()) return true;
2466 if (*handle_ == heap->minus_zero_value()) return true;
2467 if (*handle_ == heap->nan_value()) return true;
2468 if (*handle_ == heap->empty_string()) return true; 2485 if (*handle_ == heap->empty_string()) return true;
2469 return false; 2486 return false;
2470 } 2487 }
2471 2488
2472 virtual Representation RequiredInputRepresentation(int index) { 2489 virtual Representation RequiredInputRepresentation(int index) {
2473 return Representation::None(); 2490 return Representation::None();
2474 } 2491 }
2475 2492
2493 void EnsureHasHandle(Factory* factory);
2494 bool IsTagged() {
2495 ASSERT(has_int32_value_ || has_double_value_ || !handle_.is_null());
2496 return !(has_int32_value_ || has_double_value_);
2497 }
2498
2476 virtual bool IsConvertibleToInteger() const { 2499 virtual bool IsConvertibleToInteger() const {
2477 if (handle_->IsSmi()) return true; 2500 return has_int32_value_;
2478 if (handle_->IsHeapNumber() &&
2479 (HeapNumber::cast(*handle_)->value() ==
2480 static_cast<double>(NumberToInt32(*handle_)))) return true;
2481 return false;
2482 } 2501 }
2483 2502
2484 virtual bool EmitAtUses() { return !representation().IsDouble(); } 2503 virtual bool EmitAtUses() { return !representation().IsDouble(); }
2485 virtual HValue* Canonicalize(); 2504 virtual HValue* Canonicalize();
2486 virtual void PrintDataTo(StringStream* stream); 2505 virtual void PrintDataTo(StringStream* stream);
2487 virtual HType CalculateInferredType(); 2506 virtual HType CalculateInferredType();
2488 bool IsInteger() const { return handle_->IsSmi(); } 2507 bool IsInteger() const { return handle_was_smi_; }
2489 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 2508 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
2490 HConstant* CopyToTruncatedInt32(Zone* zone) const; 2509 HConstant* CopyToTruncatedInt32(Zone* zone) const;
2491 bool HasInteger32Value() const { return has_int32_value_; } 2510 bool HasInteger32Value() const { return has_int32_value_; }
2492 int32_t Integer32Value() const { 2511 int32_t Integer32Value() const {
2493 ASSERT(HasInteger32Value()); 2512 ASSERT(HasInteger32Value());
2494 return int32_value_; 2513 return int32_value_;
2495 } 2514 }
2496 bool HasDoubleValue() const { return has_double_value_; } 2515 bool HasDoubleValue() const { return has_double_value_; }
2497 double DoubleValue() const { 2516 double DoubleValue() const {
2498 ASSERT(HasDoubleValue()); 2517 ASSERT(HasDoubleValue());
2499 return double_value_; 2518 return double_value_;
2500 } 2519 }
2501 bool HasNumberValue() const { return has_int32_value_ || has_double_value_; } 2520 bool HasNumberValue() const { return has_double_value_; }
2502 int32_t NumberValueAsInteger32() const { 2521 int32_t NumberValueAsInteger32() const {
2503 ASSERT(HasNumberValue()); 2522 ASSERT(HasNumberValue());
2504 if (has_int32_value_) return int32_value_; 2523 return int32_value_;
2505 return DoubleToInt32(double_value_);
2506 } 2524 }
2507 bool HasStringValue() const { return handle_->IsString(); } 2525 bool IsString() const { return is_string_; }
2526 bool IsBoolean() const { return is_boolean_; }
2527 bool IsSymbol() { return is_symbol_; }
2508 2528
2509 bool ToBoolean() const; 2529 bool ToBoolean() const;
2510 2530
2511 virtual intptr_t Hashcode() { 2531 virtual intptr_t Hashcode() {
2512 ASSERT(!HEAP->allow_allocation(false)); 2532 ASSERT(!HEAP->allow_allocation(false));
2513 intptr_t hash = reinterpret_cast<intptr_t>(*handle()); 2533 intptr_t hash;
2514 // Prevent smis from having fewer hash values when truncated to 2534
2515 // the least significant bits. 2535 if (has_int32_value_) {
2516 const int kShiftSize = kSmiShiftSize + kSmiTagSize; 2536 hash = static_cast<intptr_t>(int32_value_);
2517 STATIC_ASSERT(kShiftSize != 0); 2537 // Prevent smis from having fewer hash values when truncated to
2518 return hash ^ (hash >> kShiftSize); 2538 // the least significant bits.
2539 const int kShiftSize = kSmiShiftSize + kSmiTagSize;
2540 STATIC_ASSERT(kShiftSize != 0);
2541 hash = hash ^ (hash >> kShiftSize);
2542 } else if (has_double_value_) {
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;
2519 } 2550 }
2520 2551
2521 #ifdef DEBUG 2552 #ifdef DEBUG
2522 virtual void Verify() { } 2553 virtual void Verify() { }
2523 #endif 2554 #endif
2524 2555
2525 DECLARE_CONCRETE_INSTRUCTION(Constant) 2556 DECLARE_CONCRETE_INSTRUCTION(Constant)
2526 2557
2527 protected: 2558 protected:
2528 virtual Range* InferRange(Zone* zone); 2559 virtual Range* InferRange(Zone* zone);
2529 2560
2530 virtual bool DataEquals(HValue* other) { 2561 virtual bool DataEquals(HValue* other) {
2531 HConstant* other_constant = HConstant::cast(other); 2562 HConstant* other_constant = HConstant::cast(other);
2532 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 }
2533 } 2575 }
2534 2576
2535 private: 2577 private:
2578 // We store the HConstant in the most specific form safely possible.
2579 // The two flags, has_int32_value_ and has_double_value_ tell us if
2580 // int32_value_ and double_value_ hold valid, safe representations
2581 // of the constant. has_int32_value_ implies has_double_value_ but
2582 // not the converse.
2583
2584 // If this is a numerical constant, handle_ either points to to the
2585 // HeapObject the constant originated from or is null. If the
2586 // constant is non-numeric, handle_ always points to a valid
2587 // constant HeapObject.
2588
2536 Handle<Object> handle_; 2589 Handle<Object> handle_;
2537 2590
2538 // The following two values represent the int32 and the double value of the
2539 // given constant if there is a lossless conversion between the constant
2540 // and the specific representation.
2541 bool has_int32_value_ : 1; 2591 bool has_int32_value_ : 1;
2542 bool has_double_value_ : 1; 2592 bool has_double_value_ : 1;
2593 bool handle_was_smi_ : 1;
2594 bool is_string_ : 1;
2595 bool is_symbol_ : 1;
2596 bool is_boolean_ : 1;
2543 int32_t int32_value_; 2597 int32_t int32_value_;
2544 double double_value_; 2598 double double_value_;
2545 }; 2599 };
2546 2600
2547 2601
2548 class HBinaryOperation: public HTemplateInstruction<3> { 2602 class HBinaryOperation: public HTemplateInstruction<3> {
2549 public: 2603 public:
2550 HBinaryOperation(HValue* context, HValue* left, HValue* right) { 2604 HBinaryOperation(HValue* context, HValue* left, HValue* right) {
2551 ASSERT(left != NULL && right != NULL); 2605 ASSERT(left != NULL && right != NULL);
2552 SetOperandAt(0, context); 2606 SetOperandAt(0, context);
(...skipping 2544 matching lines...) Expand 10 before | Expand all | Expand 10 after
5097 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5151 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5098 }; 5152 };
5099 5153
5100 5154
5101 #undef DECLARE_INSTRUCTION 5155 #undef DECLARE_INSTRUCTION
5102 #undef DECLARE_CONCRETE_INSTRUCTION 5156 #undef DECLARE_CONCRETE_INSTRUCTION
5103 5157
5104 } } // namespace v8::internal 5158 } } // namespace v8::internal
5105 5159
5106 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5160 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/ia32/lithium-codegen-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698