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

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

Issue 21173004: Version 3.20.11.1 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 4 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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 V(BackingStoreFields) \ 204 V(BackingStoreFields) \
205 V(Calls) \ 205 V(Calls) \
206 V(ContextSlots) \ 206 V(ContextSlots) \
207 V(DoubleArrayElements) \ 207 V(DoubleArrayElements) \
208 V(DoubleFields) \ 208 V(DoubleFields) \
209 V(ElementsKind) \ 209 V(ElementsKind) \
210 V(ElementsPointer) \ 210 V(ElementsPointer) \
211 V(GlobalVars) \ 211 V(GlobalVars) \
212 V(InobjectFields) \ 212 V(InobjectFields) \
213 V(OsrEntries) \ 213 V(OsrEntries) \
214 V(ExternalMemory) 214 V(SpecializedArrayElements)
215 215
216 216
217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 217 #define DECLARE_ABSTRACT_INSTRUCTION(type) \
218 virtual bool Is##type() const { return true; } \ 218 virtual bool Is##type() const { return true; } \
219 static H##type* cast(HValue* value) { \ 219 static H##type* cast(HValue* value) { \
220 ASSERT(value->Is##type()); \ 220 ASSERT(value->Is##type()); \
221 return reinterpret_cast<H##type*>(value); \ 221 return reinterpret_cast<H##type*>(value); \
222 } 222 }
223 223
224 224
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 return reinterpret_cast<intptr_t>(raw_address_); 343 return reinterpret_cast<intptr_t>(raw_address_);
344 } 344 }
345 345
346 private: 346 private:
347 Address raw_address_; 347 Address raw_address_;
348 }; 348 };
349 349
350 350
351 class HType { 351 class HType {
352 public: 352 public:
353 static HType None() { return HType(kNone); } 353 HType() : type_(kUninitialized) { }
354
354 static HType Tagged() { return HType(kTagged); } 355 static HType Tagged() { return HType(kTagged); }
355 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } 356 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
356 static HType TaggedNumber() { return HType(kTaggedNumber); } 357 static HType TaggedNumber() { return HType(kTaggedNumber); }
357 static HType Smi() { return HType(kSmi); } 358 static HType Smi() { return HType(kSmi); }
358 static HType HeapNumber() { return HType(kHeapNumber); } 359 static HType HeapNumber() { return HType(kHeapNumber); }
359 static HType String() { return HType(kString); } 360 static HType String() { return HType(kString); }
360 static HType Boolean() { return HType(kBoolean); } 361 static HType Boolean() { return HType(kBoolean); }
361 static HType NonPrimitive() { return HType(kNonPrimitive); } 362 static HType NonPrimitive() { return HType(kNonPrimitive); }
362 static HType JSArray() { return HType(kJSArray); } 363 static HType JSArray() { return HType(kJSArray); }
363 static HType JSObject() { return HType(kJSObject); } 364 static HType JSObject() { return HType(kJSObject); }
365 static HType Uninitialized() { return HType(kUninitialized); }
364 366
365 // Return the weakest (least precise) common type. 367 // Return the weakest (least precise) common type.
366 HType Combine(HType other) { 368 HType Combine(HType other) {
367 return HType(static_cast<Type>(type_ & other.type_)); 369 return HType(static_cast<Type>(type_ & other.type_));
368 } 370 }
369 371
370 bool Equals(const HType& other) const { 372 bool Equals(const HType& other) const {
371 return type_ == other.type_; 373 return type_ == other.type_;
372 } 374 }
373 375
374 bool IsSubtypeOf(const HType& other) { 376 bool IsSubtypeOf(const HType& other) {
375 return Combine(other).Equals(other); 377 return Combine(other).Equals(other);
376 } 378 }
377 379
378 bool IsTagged() const { 380 bool IsTagged() const {
381 ASSERT(type_ != kUninitialized);
379 return ((type_ & kTagged) == kTagged); 382 return ((type_ & kTagged) == kTagged);
380 } 383 }
381 384
382 bool IsTaggedPrimitive() const { 385 bool IsTaggedPrimitive() const {
386 ASSERT(type_ != kUninitialized);
383 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); 387 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
384 } 388 }
385 389
386 bool IsTaggedNumber() const { 390 bool IsTaggedNumber() const {
391 ASSERT(type_ != kUninitialized);
387 return ((type_ & kTaggedNumber) == kTaggedNumber); 392 return ((type_ & kTaggedNumber) == kTaggedNumber);
388 } 393 }
389 394
390 bool IsSmi() const { 395 bool IsSmi() const {
396 ASSERT(type_ != kUninitialized);
391 return ((type_ & kSmi) == kSmi); 397 return ((type_ & kSmi) == kSmi);
392 } 398 }
393 399
394 bool IsHeapNumber() const { 400 bool IsHeapNumber() const {
401 ASSERT(type_ != kUninitialized);
395 return ((type_ & kHeapNumber) == kHeapNumber); 402 return ((type_ & kHeapNumber) == kHeapNumber);
396 } 403 }
397 404
398 bool IsString() const { 405 bool IsString() const {
406 ASSERT(type_ != kUninitialized);
399 return ((type_ & kString) == kString); 407 return ((type_ & kString) == kString);
400 } 408 }
401 409
402 bool IsNonString() const { 410 bool IsNonString() const {
403 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || 411 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() ||
404 IsBoolean() || IsJSArray(); 412 IsBoolean() || IsJSArray();
405 } 413 }
406 414
407 bool IsBoolean() const { 415 bool IsBoolean() const {
416 ASSERT(type_ != kUninitialized);
408 return ((type_ & kBoolean) == kBoolean); 417 return ((type_ & kBoolean) == kBoolean);
409 } 418 }
410 419
411 bool IsNonPrimitive() const { 420 bool IsNonPrimitive() const {
421 ASSERT(type_ != kUninitialized);
412 return ((type_ & kNonPrimitive) == kNonPrimitive); 422 return ((type_ & kNonPrimitive) == kNonPrimitive);
413 } 423 }
414 424
415 bool IsJSArray() const { 425 bool IsJSArray() const {
426 ASSERT(type_ != kUninitialized);
416 return ((type_ & kJSArray) == kJSArray); 427 return ((type_ & kJSArray) == kJSArray);
417 } 428 }
418 429
419 bool IsJSObject() const { 430 bool IsJSObject() const {
431 ASSERT(type_ != kUninitialized);
420 return ((type_ & kJSObject) == kJSObject); 432 return ((type_ & kJSObject) == kJSObject);
421 } 433 }
422 434
435 bool IsUninitialized() const {
436 return type_ == kUninitialized;
437 }
438
423 bool IsHeapObject() const { 439 bool IsHeapObject() const {
440 ASSERT(type_ != kUninitialized);
424 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); 441 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive();
425 } 442 }
426 443
427 bool ToStringOrToNumberCanBeObserved(Representation representation) {
428 switch (type_) {
429 case kTaggedPrimitive: // fallthru
430 case kTaggedNumber: // fallthru
431 case kSmi: // fallthru
432 case kHeapNumber: // fallthru
433 case kString: // fallthru
434 case kBoolean:
435 return false;
436 case kJSArray: // fallthru
437 case kJSObject:
438 return true;
439 case kTagged:
440 break;
441 }
442 return !representation.IsSmiOrInteger32() && !representation.IsDouble();
443 }
444
445 static HType TypeFromValue(Handle<Object> value); 444 static HType TypeFromValue(Handle<Object> value);
446 445
447 const char* ToString(); 446 const char* ToString();
448 447
449 private: 448 private:
450 enum Type { 449 enum Type {
451 kNone = 0x0, // 0000 0000 0000 0000
452 kTagged = 0x1, // 0000 0000 0000 0001 450 kTagged = 0x1, // 0000 0000 0000 0001
453 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 451 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
454 kTaggedNumber = 0xd, // 0000 0000 0000 1101 452 kTaggedNumber = 0xd, // 0000 0000 0000 1101
455 kSmi = 0x1d, // 0000 0000 0001 1101 453 kSmi = 0x1d, // 0000 0000 0001 1101
456 kHeapNumber = 0x2d, // 0000 0000 0010 1101 454 kHeapNumber = 0x2d, // 0000 0000 0010 1101
457 kString = 0x45, // 0000 0000 0100 0101 455 kString = 0x45, // 0000 0000 0100 0101
458 kBoolean = 0x85, // 0000 0000 1000 0101 456 kBoolean = 0x85, // 0000 0000 1000 0101
459 kNonPrimitive = 0x101, // 0000 0001 0000 0001 457 kNonPrimitive = 0x101, // 0000 0001 0000 0001
460 kJSObject = 0x301, // 0000 0011 0000 0001 458 kJSObject = 0x301, // 0000 0011 0000 0001
461 kJSArray = 0x701 // 0000 0111 0000 0001 459 kJSArray = 0x701, // 0000 0111 0000 0001
460 kUninitialized = 0x1fff // 0001 1111 1111 1111
462 }; 461 };
463 462
464 // Make sure type fits in int16. 463 // Make sure type fits in int16.
465 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte))); 464 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
466 465
467 explicit HType(Type t) : type_(t) { } 466 explicit HType(Type t) : type_(t) { }
468 467
469 int16_t type_; 468 int16_t type_;
470 }; 469 };
471 470
472 471
473 class HUseListNode: public ZoneObject { 472 class HUseListNode: public ZoneObject {
474 public: 473 public:
475 HUseListNode(HValue* value, int index, HUseListNode* tail) 474 HUseListNode(HValue* value, int index, HUseListNode* tail)
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 1138
1140 bool TryGuaranteeRange(HValue* upper_bound); 1139 bool TryGuaranteeRange(HValue* upper_bound);
1141 virtual bool TryDecompose(DecompositionResult* decomposition) { 1140 virtual bool TryDecompose(DecompositionResult* decomposition) {
1142 if (RedefinedOperand() != NULL) { 1141 if (RedefinedOperand() != NULL) {
1143 return RedefinedOperand()->TryDecompose(decomposition); 1142 return RedefinedOperand()->TryDecompose(decomposition);
1144 } else { 1143 } else {
1145 return false; 1144 return false;
1146 } 1145 }
1147 } 1146 }
1148 1147
1149 // Returns true conservatively if the program might be able to observe a
1150 // ToString() operation on this value.
1151 bool ToStringCanBeObserved() const {
1152 return type().ToStringOrToNumberCanBeObserved(representation());
1153 }
1154
1155 // Returns true conservatively if the program might be able to observe a
1156 // ToNumber() operation on this value.
1157 bool ToNumberCanBeObserved() const {
1158 return type().ToStringOrToNumberCanBeObserved(representation());
1159 }
1160
1161 protected: 1148 protected:
1162 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); 1149 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1163 1150
1164 enum RangeGuaranteeDirection { 1151 enum RangeGuaranteeDirection {
1165 DIRECTION_NONE = 0, 1152 DIRECTION_NONE = 0,
1166 DIRECTION_UPPER = 1, 1153 DIRECTION_UPPER = 1,
1167 DIRECTION_LOWER = 2, 1154 DIRECTION_LOWER = 2,
1168 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER 1155 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1169 }; 1156 };
1170 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} 1157 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 // change. The external array of a specialized array elements object cannot 2675 // change. The external array of a specialized array elements object cannot
2689 // change once set, so it's no necessary to introduce any additional 2676 // change once set, so it's no necessary to introduce any additional
2690 // dependencies on top of the inputs. 2677 // dependencies on top of the inputs.
2691 SetFlag(kUseGVN); 2678 SetFlag(kUseGVN);
2692 } 2679 }
2693 2680
2694 virtual Representation RequiredInputRepresentation(int index) { 2681 virtual Representation RequiredInputRepresentation(int index) {
2695 return Representation::Tagged(); 2682 return Representation::Tagged();
2696 } 2683 }
2697 2684
2698 virtual HType CalculateInferredType() {
2699 return HType::None();
2700 }
2701
2702 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) 2685 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
2703 2686
2704 protected: 2687 protected:
2705 virtual bool DataEquals(HValue* other) { return true; } 2688 virtual bool DataEquals(HValue* other) { return true; }
2706 2689
2707 private: 2690 private:
2708 virtual bool IsDeletable() const { return true; } 2691 virtual bool IsDeletable() const { return true; }
2709 }; 2692 };
2710 2693
2711 2694
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 return Representation::Tagged(); 2930 return Representation::Tagged();
2948 } 2931 }
2949 2932
2950 virtual HType CalculateInferredType(); 2933 virtual HType CalculateInferredType();
2951 2934
2952 #ifdef DEBUG 2935 #ifdef DEBUG
2953 virtual void Verify(); 2936 virtual void Verify();
2954 #endif 2937 #endif
2955 2938
2956 virtual HValue* Canonicalize() { 2939 virtual HValue* Canonicalize() {
2957 return value()->type().IsHeapObject() ? NULL : this; 2940 HType value_type = value()->type();
2941 if (!value_type.IsUninitialized() && value_type.IsHeapObject()) {
2942 return NULL;
2943 }
2944 return this;
2958 } 2945 }
2959 2946
2960 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) 2947 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
2961 2948
2962 protected: 2949 protected:
2963 virtual bool DataEquals(HValue* other) { return true; } 2950 virtual bool DataEquals(HValue* other) { return true; }
2964 }; 2951 };
2965 2952
2966 2953
2967 class HCheckPrototypeMaps: public HTemplateInstruction<0> { 2954 class HCheckPrototypeMaps: public HTemplateInstruction<0> {
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 int phi_id() { return phi_id_; } 3336 int phi_id() { return phi_id_; }
3350 3337
3351 static HPhi* cast(HValue* value) { 3338 static HPhi* cast(HValue* value) {
3352 ASSERT(value->IsPhi()); 3339 ASSERT(value->IsPhi());
3353 return reinterpret_cast<HPhi*>(value); 3340 return reinterpret_cast<HPhi*>(value);
3354 } 3341 }
3355 virtual Opcode opcode() const { return HValue::kPhi; } 3342 virtual Opcode opcode() const { return HValue::kPhi; }
3356 3343
3357 void SimplifyConstantInputs(); 3344 void SimplifyConstantInputs();
3358 3345
3346 // TODO(titzer): we can't eliminate the receiver for generating backtraces
3347 virtual bool IsDeletable() const { return !IsReceiver(); }
3348
3359 protected: 3349 protected:
3360 virtual void DeleteFromGraph(); 3350 virtual void DeleteFromGraph();
3361 virtual void InternalSetOperandAt(int index, HValue* value) { 3351 virtual void InternalSetOperandAt(int index, HValue* value) {
3362 inputs_[index] = value; 3352 inputs_[index] = value;
3363 } 3353 }
3364 3354
3365 virtual bool IsRelationTrueInternal(NumericRelation relation, 3355 virtual bool IsRelationTrueInternal(NumericRelation relation,
3366 HValue* other, 3356 HValue* other,
3367 int offset = 0, 3357 int offset = 0,
3368 int scale = 0); 3358 int scale = 0);
3369 3359
3370 private: 3360 private:
3371 ZoneList<HValue*> inputs_; 3361 ZoneList<HValue*> inputs_;
3372 int merged_index_; 3362 int merged_index_;
3373 3363
3374 int non_phi_uses_[Representation::kNumRepresentations]; 3364 int non_phi_uses_[Representation::kNumRepresentations];
3375 int indirect_uses_[Representation::kNumRepresentations]; 3365 int indirect_uses_[Representation::kNumRepresentations];
3376 int phi_id_; 3366 int phi_id_;
3377 InductionVariableData* induction_variable_data_; 3367 InductionVariableData* induction_variable_data_;
3378
3379 // TODO(titzer): we can't eliminate the receiver for generating backtraces
3380 virtual bool IsDeletable() const { return !IsReceiver(); }
3381 }; 3368 };
3382 3369
3383 3370
3384 class HInductionVariableAnnotation : public HUnaryOperation { 3371 class HInductionVariableAnnotation : public HUnaryOperation {
3385 public: 3372 public:
3386 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, 3373 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3387 NumericRelation relation, 3374 NumericRelation relation,
3388 int operand_index); 3375 int operand_index);
3389 3376
3390 NumericRelation relation() { return relation_; } 3377 NumericRelation relation() { return relation_; }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 bool is_not_in_new_space = true, 3464 bool is_not_in_new_space = true,
3478 Handle<Object> optional_handle = Handle<Object>::null()); 3465 Handle<Object> optional_handle = Handle<Object>::null());
3479 HConstant(Handle<Object> handle, 3466 HConstant(Handle<Object> handle,
3480 UniqueValueId unique_id, 3467 UniqueValueId unique_id,
3481 Representation r, 3468 Representation r,
3482 HType type, 3469 HType type,
3483 bool is_internalized_string, 3470 bool is_internalized_string,
3484 bool is_not_in_new_space, 3471 bool is_not_in_new_space,
3485 bool is_cell, 3472 bool is_cell,
3486 bool boolean_value); 3473 bool boolean_value);
3487 explicit HConstant(ExternalReference reference);
3488 3474
3489 Handle<Object> handle() { 3475 Handle<Object> handle() {
3490 if (handle_.is_null()) { 3476 if (handle_.is_null()) {
3491 Factory* factory = Isolate::Current()->factory(); 3477 Factory* factory = Isolate::Current()->factory();
3492 // Default arguments to is_not_in_new_space depend on this heap number 3478 // Default arguments to is_not_in_new_space depend on this heap number
3493 // to be tenured so that it's guaranteed not be be located in new space. 3479 // to be tenured so that it's guaranteed not be be located in new space.
3494 handle_ = factory->NewNumber(double_value_, TENURED); 3480 handle_ = factory->NewNumber(double_value_, TENURED);
3495 } 3481 }
3496 AllowDeferredHandleDereference smi_check; 3482 AllowDeferredHandleDereference smi_check;
3497 ASSERT(has_int32_value_ || !handle_->IsSmi()); 3483 ASSERT(has_int32_value_ || !handle_->IsSmi());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3542 } 3528 }
3543 3529
3544 virtual Representation RequiredInputRepresentation(int index) { 3530 virtual Representation RequiredInputRepresentation(int index) {
3545 return Representation::None(); 3531 return Representation::None();
3546 } 3532 }
3547 3533
3548 virtual Representation KnownOptimalRepresentation() { 3534 virtual Representation KnownOptimalRepresentation() {
3549 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); 3535 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
3550 if (HasInteger32Value()) return Representation::Integer32(); 3536 if (HasInteger32Value()) return Representation::Integer32();
3551 if (HasNumberValue()) return Representation::Double(); 3537 if (HasNumberValue()) return Representation::Double();
3552 if (HasExternalReferenceValue()) return Representation::External();
3553 return Representation::Tagged(); 3538 return Representation::Tagged();
3554 } 3539 }
3555 3540
3556 virtual bool EmitAtUses(); 3541 virtual bool EmitAtUses();
3557 virtual void PrintDataTo(StringStream* stream); 3542 virtual void PrintDataTo(StringStream* stream);
3543 virtual HType CalculateInferredType();
3558 bool IsInteger() { return handle()->IsSmi(); } 3544 bool IsInteger() { return handle()->IsSmi(); }
3559 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; 3545 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3560 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone); 3546 Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
3561 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone); 3547 Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
3562 bool HasInteger32Value() const { return has_int32_value_; } 3548 bool HasInteger32Value() const { return has_int32_value_; }
3563 int32_t Integer32Value() const { 3549 int32_t Integer32Value() const {
3564 ASSERT(HasInteger32Value()); 3550 ASSERT(HasInteger32Value());
3565 return int32_value_; 3551 return int32_value_;
3566 } 3552 }
3567 bool HasSmiValue() const { return has_smi_value_; } 3553 bool HasSmiValue() const { return has_smi_value_; }
(...skipping 16 matching lines...) Expand all
3584 int32_t NumberValueAsInteger32() const { 3570 int32_t NumberValueAsInteger32() const {
3585 ASSERT(HasNumberValue()); 3571 ASSERT(HasNumberValue());
3586 // Irrespective of whether a numeric HConstant can be safely 3572 // Irrespective of whether a numeric HConstant can be safely
3587 // represented as an int32, we store the (in some cases lossy) 3573 // represented as an int32, we store the (in some cases lossy)
3588 // representation of the number in int32_value_. 3574 // representation of the number in int32_value_.
3589 return int32_value_; 3575 return int32_value_;
3590 } 3576 }
3591 bool HasStringValue() const { 3577 bool HasStringValue() const {
3592 if (has_double_value_ || has_int32_value_) return false; 3578 if (has_double_value_ || has_int32_value_) return false;
3593 ASSERT(!handle_.is_null()); 3579 ASSERT(!handle_.is_null());
3594 return type_.IsString(); 3580 return type_from_value_.IsString();
3595 } 3581 }
3596 Handle<String> StringValue() const { 3582 Handle<String> StringValue() const {
3597 ASSERT(HasStringValue()); 3583 ASSERT(HasStringValue());
3598 return Handle<String>::cast(handle_); 3584 return Handle<String>::cast(handle_);
3599 } 3585 }
3600 bool HasInternalizedStringValue() const { 3586 bool HasInternalizedStringValue() const {
3601 return HasStringValue() && is_internalized_string_; 3587 return HasStringValue() && is_internalized_string_;
3602 } 3588 }
3603 3589
3604 bool HasExternalReferenceValue() const {
3605 return has_external_reference_value_;
3606 }
3607 ExternalReference ExternalReferenceValue() const {
3608 return external_reference_value_;
3609 }
3610
3611 bool BooleanValue() const { return boolean_value_; } 3590 bool BooleanValue() const { return boolean_value_; }
3612 3591
3613 virtual intptr_t Hashcode() { 3592 virtual intptr_t Hashcode() {
3614 if (has_int32_value_) { 3593 if (has_int32_value_) {
3615 return static_cast<intptr_t>(int32_value_); 3594 return static_cast<intptr_t>(int32_value_);
3616 } else if (has_double_value_) { 3595 } else if (has_double_value_) {
3617 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3596 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3618 } else if (has_external_reference_value_) {
3619 return reinterpret_cast<intptr_t>(external_reference_value_.address());
3620 } else { 3597 } else {
3621 ASSERT(!handle_.is_null()); 3598 ASSERT(!handle_.is_null());
3622 return unique_id_.Hashcode(); 3599 return unique_id_.Hashcode();
3623 } 3600 }
3624 } 3601 }
3625 3602
3626 virtual void FinalizeUniqueValueId() { 3603 virtual void FinalizeUniqueValueId() {
3627 if (!has_double_value_ && !has_external_reference_value_) { 3604 if (!has_double_value_) {
3628 ASSERT(!handle_.is_null()); 3605 ASSERT(!handle_.is_null());
3629 unique_id_ = UniqueValueId(handle_); 3606 unique_id_ = UniqueValueId(handle_);
3630 } 3607 }
3631 } 3608 }
3632 3609
3633 bool UniqueValueIdsMatch(UniqueValueId other) { 3610 bool UniqueValueIdsMatch(UniqueValueId other) {
3634 return !has_double_value_ && !has_external_reference_value_ && 3611 return !has_double_value_ && unique_id_ == other;
3635 unique_id_ == other;
3636 } 3612 }
3637 3613
3638 #ifdef DEBUG 3614 #ifdef DEBUG
3639 virtual void Verify() { } 3615 virtual void Verify() { }
3640 #endif 3616 #endif
3641 3617
3642 DECLARE_CONCRETE_INSTRUCTION(Constant) 3618 DECLARE_CONCRETE_INSTRUCTION(Constant)
3643 3619
3644 protected: 3620 protected:
3645 virtual Range* InferRange(Zone* zone); 3621 virtual Range* InferRange(Zone* zone);
3646 3622
3647 virtual bool DataEquals(HValue* other) { 3623 virtual bool DataEquals(HValue* other) {
3648 HConstant* other_constant = HConstant::cast(other); 3624 HConstant* other_constant = HConstant::cast(other);
3649 if (has_int32_value_) { 3625 if (has_int32_value_) {
3650 return other_constant->has_int32_value_ && 3626 return other_constant->has_int32_value_ &&
3651 int32_value_ == other_constant->int32_value_; 3627 int32_value_ == other_constant->int32_value_;
3652 } else if (has_double_value_) { 3628 } else if (has_double_value_) {
3653 return other_constant->has_double_value_ && 3629 return other_constant->has_double_value_ &&
3654 BitCast<int64_t>(double_value_) == 3630 BitCast<int64_t>(double_value_) ==
3655 BitCast<int64_t>(other_constant->double_value_); 3631 BitCast<int64_t>(other_constant->double_value_);
3656 } else if (has_external_reference_value_) {
3657 return other_constant->has_external_reference_value_ &&
3658 external_reference_value_ ==
3659 other_constant->external_reference_value_;
3660 } else { 3632 } else {
3661 ASSERT(!handle_.is_null()); 3633 ASSERT(!handle_.is_null());
3662 return !other_constant->handle_.is_null() && 3634 return !other_constant->handle_.is_null() &&
3663 unique_id_ == other_constant->unique_id_; 3635 unique_id_ == other_constant->unique_id_;
3664 } 3636 }
3665 } 3637 }
3666 3638
3667 private: 3639 private:
3668 void Initialize(Representation r); 3640 void Initialize(Representation r);
3669 3641
3670 virtual bool IsDeletable() const { return true; } 3642 virtual bool IsDeletable() const { return true; }
3671 3643
3672 // If this is a numerical constant, handle_ either points to to the 3644 // If this is a numerical constant, handle_ either points to to the
3673 // HeapObject the constant originated from or is null. If the 3645 // HeapObject the constant originated from or is null. If the
3674 // constant is non-numeric, handle_ always points to a valid 3646 // constant is non-numeric, handle_ always points to a valid
3675 // constant HeapObject. 3647 // constant HeapObject.
3676 Handle<Object> handle_; 3648 Handle<Object> handle_;
3677 UniqueValueId unique_id_; 3649 UniqueValueId unique_id_;
3678 3650
3679 // We store the HConstant in the most specific form safely possible. 3651 // We store the HConstant in the most specific form safely possible.
3680 // The two flags, has_int32_value_ and has_double_value_ tell us if 3652 // The two flags, has_int32_value_ and has_double_value_ tell us if
3681 // int32_value_ and double_value_ hold valid, safe representations 3653 // int32_value_ and double_value_ hold valid, safe representations
3682 // of the constant. has_int32_value_ implies has_double_value_ but 3654 // of the constant. has_int32_value_ implies has_double_value_ but
3683 // not the converse. 3655 // not the converse.
3684 bool has_smi_value_ : 1; 3656 bool has_smi_value_ : 1;
3685 bool has_int32_value_ : 1; 3657 bool has_int32_value_ : 1;
3686 bool has_double_value_ : 1; 3658 bool has_double_value_ : 1;
3687 bool has_external_reference_value_ : 1;
3688 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. 3659 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
3689 bool is_not_in_new_space_ : 1; 3660 bool is_not_in_new_space_ : 1;
3690 bool is_cell_ : 1; 3661 bool is_cell_ : 1;
3691 bool boolean_value_ : 1; 3662 bool boolean_value_ : 1;
3692 int32_t int32_value_; 3663 int32_t int32_value_;
3693 double double_value_; 3664 double double_value_;
3694 ExternalReference external_reference_value_; 3665 HType type_from_value_;
3695 }; 3666 };
3696 3667
3697 3668
3698 class HBinaryOperation: public HTemplateInstruction<3> { 3669 class HBinaryOperation: public HTemplateInstruction<3> {
3699 public: 3670 public:
3700 HBinaryOperation(HValue* context, HValue* left, HValue* right) 3671 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3701 : observed_output_representation_(Representation::None()) { 3672 : observed_output_representation_(Representation::None()) {
3702 ASSERT(left != NULL && right != NULL); 3673 ASSERT(left != NULL && right != NULL);
3703 SetOperandAt(0, context); 3674 SetOperandAt(0, context);
3704 SetOperandAt(1, left); 3675 SetOperandAt(1, left);
3705 SetOperandAt(2, right); 3676 SetOperandAt(2, right);
3706 observed_input_representation_[0] = Representation::None(); 3677 observed_input_representation_[0] = Representation::None();
3707 observed_input_representation_[1] = Representation::None(); 3678 observed_input_representation_[1] = Representation::None();
3708 } 3679 }
3709 3680
3710 HValue* context() const { return OperandAt(0); } 3681 HValue* context() { return OperandAt(0); }
3711 HValue* left() const { return OperandAt(1); } 3682 HValue* left() { return OperandAt(1); }
3712 HValue* right() const { return OperandAt(2); } 3683 HValue* right() { return OperandAt(2); }
3713 3684
3714 // True if switching left and right operands likely generates better code. 3685 // True if switching left and right operands likely generates better code.
3715 bool AreOperandsBetterSwitched() { 3686 bool AreOperandsBetterSwitched() {
3716 if (!IsCommutative()) return false; 3687 if (!IsCommutative()) return false;
3717 3688
3718 // Constant operands are better off on the right, they can be inlined in 3689 // Constant operands are better off on the right, they can be inlined in
3719 // many situations on most platforms. 3690 // many situations on most platforms.
3720 if (left()->IsConstant()) return true; 3691 if (left()->IsConstant()) return true;
3721 if (right()->IsConstant()) return false; 3692 if (right()->IsConstant()) return false;
3722 3693
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 base_ = index(); 3927 base_ = index();
3957 offset_ = 0; 3928 offset_ = 0;
3958 scale_ = 0; 3929 scale_ = 0;
3959 return false; 3930 return false;
3960 } 3931 }
3961 } 3932 }
3962 3933
3963 virtual Representation RequiredInputRepresentation(int arg_index) { 3934 virtual Representation RequiredInputRepresentation(int arg_index) {
3964 return representation(); 3935 return representation();
3965 } 3936 }
3937 virtual bool IsDeletable() const {
3938 return skip_check() && !FLAG_debug_code;
3939 }
3966 3940
3967 virtual bool IsRelationTrueInternal(NumericRelation relation, 3941 virtual bool IsRelationTrueInternal(NumericRelation relation,
3968 HValue* related_value, 3942 HValue* related_value,
3969 int offset = 0, 3943 int offset = 0,
3970 int scale = 0); 3944 int scale = 0);
3971 3945
3972 virtual void PrintDataTo(StringStream* stream); 3946 virtual void PrintDataTo(StringStream* stream);
3973 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 3947 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
3974 3948
3975 HValue* index() { return OperandAt(0); } 3949 HValue* index() { return OperandAt(0); }
(...skipping 16 matching lines...) Expand all
3992 } 3966 }
3993 3967
3994 virtual bool DataEquals(HValue* other) { return true; } 3968 virtual bool DataEquals(HValue* other) { return true; }
3995 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); 3969 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3996 bool skip_check_; 3970 bool skip_check_;
3997 HValue* base_; 3971 HValue* base_;
3998 int offset_; 3972 int offset_;
3999 int scale_; 3973 int scale_;
4000 RangeGuaranteeDirection responsibility_direction_; 3974 RangeGuaranteeDirection responsibility_direction_;
4001 bool allow_equality_; 3975 bool allow_equality_;
4002
4003 private:
4004 virtual bool IsDeletable() const {
4005 return skip_check() && !FLAG_debug_code;
4006 }
4007 }; 3976 };
4008 3977
4009 3978
4010 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { 3979 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
4011 public: 3980 public:
4012 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { 3981 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
4013 DecompositionResult decomposition; 3982 DecompositionResult decomposition;
4014 if (check->index()->TryDecompose(&decomposition)) { 3983 if (check->index()->TryDecompose(&decomposition)) {
4015 SetOperandAt(0, decomposition.base()); 3984 SetOperandAt(0, decomposition.base());
4016 SetOperandAt(1, check); 3985 SetOperandAt(1, check);
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 4785
4817 virtual Representation observed_input_representation(int index) { 4786 virtual Representation observed_input_representation(int index) {
4818 return RequiredInputRepresentation(index); 4787 return RequiredInputRepresentation(index);
4819 } 4788 }
4820 4789
4821 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 4790 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
4822 4791
4823 virtual Representation RepresentationFromInputs() { 4792 virtual Representation RepresentationFromInputs() {
4824 Representation left_rep = left()->representation(); 4793 Representation left_rep = left()->representation();
4825 Representation right_rep = right()->representation(); 4794 Representation right_rep = right()->representation();
4826 Representation result = Representation::Smi(); 4795 // TODO(verwaest): Initialize to Smi once lithium-codegen has been fixed.
4796 Representation result = Representation::Integer32();
4827 result = result.generalize(left_rep); 4797 result = result.generalize(left_rep);
4828 result = result.generalize(right_rep); 4798 result = result.generalize(right_rep);
4829 if (result.IsTagged()) return Representation::Double(); 4799 if (result.IsTagged()) return Representation::Double();
4830 return result; 4800 return result;
4831 } 4801 }
4832 4802
4833 virtual bool IsCommutative() const { return true; } 4803 virtual bool IsCommutative() const { return true; }
4834 4804
4835 Operation operation() { return operation_; } 4805 Operation operation() { return operation_; }
4836 4806
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4914 static HInstruction* New(Zone* zone, 4884 static HInstruction* New(Zone* zone,
4915 HValue* context, 4885 HValue* context,
4916 HValue* left, 4886 HValue* left,
4917 HValue* right); 4887 HValue* right);
4918 4888
4919 virtual Range* InferRange(Zone* zone); 4889 virtual Range* InferRange(Zone* zone);
4920 4890
4921 virtual void UpdateRepresentation(Representation new_rep, 4891 virtual void UpdateRepresentation(Representation new_rep,
4922 HInferRepresentationPhase* h_infer, 4892 HInferRepresentationPhase* h_infer,
4923 const char* reason) { 4893 const char* reason) {
4924 if (new_rep.IsSmi() && 4894 if (new_rep.IsSmi()) new_rep = Representation::Integer32();
4925 !(right()->IsInteger32Constant() &&
4926 right()->GetInteger32Constant() >= 0)) {
4927 new_rep = Representation::Integer32();
4928 }
4929 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); 4895 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
4930 } 4896 }
4931 4897
4932 DECLARE_CONCRETE_INSTRUCTION(Shl) 4898 DECLARE_CONCRETE_INSTRUCTION(Shl)
4933 4899
4934 protected: 4900 protected:
4935 virtual bool DataEquals(HValue* other) { return true; } 4901 virtual bool DataEquals(HValue* other) { return true; }
4936 4902
4937 private: 4903 private:
4938 HShl(HValue* context, HValue* left, HValue* right) 4904 HShl(HValue* context, HValue* left, HValue* right)
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
5581 int slot_index_; 5547 int slot_index_;
5582 Mode mode_; 5548 Mode mode_;
5583 }; 5549 };
5584 5550
5585 5551
5586 // Represents an access to a portion of an object, such as the map pointer, 5552 // Represents an access to a portion of an object, such as the map pointer,
5587 // array elements pointer, etc, but not accesses to array elements themselves. 5553 // array elements pointer, etc, but not accesses to array elements themselves.
5588 class HObjectAccess { 5554 class HObjectAccess {
5589 public: 5555 public:
5590 inline bool IsInobject() const { 5556 inline bool IsInobject() const {
5591 return portion() != kBackingStore && portion() != kExternalMemory; 5557 return portion() != kBackingStore;
5592 }
5593
5594 inline bool IsExternalMemory() const {
5595 return portion() == kExternalMemory;
5596 } 5558 }
5597 5559
5598 inline int offset() const { 5560 inline int offset() const {
5599 return OffsetField::decode(value_); 5561 return OffsetField::decode(value_);
5600 } 5562 }
5601 5563
5602 inline Representation representation() const { 5564 inline Representation representation() const {
5603 return Representation::FromKind(RepresentationField::decode(value_)); 5565 return Representation::FromKind(RepresentationField::decode(value_));
5604 } 5566 }
5605 5567
5606 inline Handle<String> name() const { 5568 inline Handle<String> name() const {
5607 return name_; 5569 return name_;
5608 } 5570 }
5609 5571
5610 inline HObjectAccess WithRepresentation(Representation representation) { 5572 inline HObjectAccess WithRepresentation(Representation representation) {
5611 return HObjectAccess(portion(), offset(), representation, name()); 5573 return HObjectAccess(portion(), offset(), representation, name());
5612 } 5574 }
5613 5575
5614 static HObjectAccess ForHeapNumberValue() { 5576 static HObjectAccess ForHeapNumberValue() {
5615 return HObjectAccess( 5577 return HObjectAccess(
5616 kDouble, HeapNumber::kValueOffset, Representation::Double()); 5578 kDouble, HeapNumber::kValueOffset, Representation::Double());
5617 } 5579 }
5618 5580
5619 static HObjectAccess ForElementsPointer() { 5581 static HObjectAccess ForElementsPointer() {
5620 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset); 5582 return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
5621 } 5583 }
5622 5584
5623 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { 5585 static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
5624 return HObjectAccess( 5586 return HObjectAccess(
5625 kArrayLengths, 5587 kArrayLengths, JSArray::kLengthOffset,
5626 JSArray::kLengthOffset, 5588 IsFastElementsKind(elements_kind) && FLAG_track_fields ?
5627 IsFastElementsKind(elements_kind) && 5589 Representation::Smi() : Representation::Tagged());
5628 FLAG_track_fields
5629 ? Representation::Smi() : Representation::Tagged());
5630 } 5590 }
5631 5591
5632 static HObjectAccess ForAllocationSiteTransitionInfo() { 5592 static HObjectAccess ForAllocationSiteTransitionInfo() {
5633 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); 5593 return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset);
5634 } 5594 }
5635 5595
5636 static HObjectAccess ForAllocationSiteWeakNext() { 5596 static HObjectAccess ForAllocationSiteWeakNext() {
5637 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset); 5597 return HObjectAccess(kInobject, AllocationSite::kWeakNextOffset);
5638 } 5598 }
5639 5599
5640 static HObjectAccess ForFixedArrayLength() { 5600 static HObjectAccess ForFixedArrayLength() {
5641 return HObjectAccess( 5601 return HObjectAccess(
5642 kArrayLengths, 5602 kArrayLengths, FixedArray::kLengthOffset,
5643 FixedArray::kLengthOffset, 5603 FLAG_track_fields ?
5644 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); 5604 Representation::Smi() : Representation::Tagged());
5645 } 5605 }
5646 5606
5647 static HObjectAccess ForPropertiesPointer() { 5607 static HObjectAccess ForPropertiesPointer() {
5648 return HObjectAccess(kInobject, JSObject::kPropertiesOffset); 5608 return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
5649 } 5609 }
5650 5610
5651 static HObjectAccess ForPrototypeOrInitialMap() { 5611 static HObjectAccess ForPrototypeOrInitialMap() {
5652 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset); 5612 return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
5653 } 5613 }
5654 5614
5655 static HObjectAccess ForMap() { 5615 static HObjectAccess ForMap() {
5656 return HObjectAccess(kMaps, JSObject::kMapOffset); 5616 return HObjectAccess(kMaps, JSObject::kMapOffset);
5657 } 5617 }
5658 5618
5659 static HObjectAccess ForPropertyCellValue() { 5619 static HObjectAccess ForPropertyCellValue() {
5660 return HObjectAccess(kInobject, PropertyCell::kValueOffset); 5620 return HObjectAccess(kInobject, PropertyCell::kValueOffset);
5661 } 5621 }
5662 5622
5663 static HObjectAccess ForCellValue() { 5623 static HObjectAccess ForCellValue() {
5664 return HObjectAccess(kInobject, Cell::kValueOffset); 5624 return HObjectAccess(kInobject, Cell::kValueOffset);
5665 } 5625 }
5666 5626
5667 static HObjectAccess ForAllocationMementoSite() { 5627 static HObjectAccess ForAllocationMementoSite() {
5668 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset); 5628 return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
5669 } 5629 }
5670 5630
5671 static HObjectAccess ForCounter() {
5672 return HObjectAccess(kExternalMemory, 0, Representation::Integer32());
5673 }
5674
5675 // Create an access to an offset in a fixed array header. 5631 // Create an access to an offset in a fixed array header.
5676 static HObjectAccess ForFixedArrayHeader(int offset); 5632 static HObjectAccess ForFixedArrayHeader(int offset);
5677 5633
5678 // Create an access to an in-object property in a JSObject. 5634 // Create an access to an in-object property in a JSObject.
5679 static HObjectAccess ForJSObjectOffset(int offset, 5635 static HObjectAccess ForJSObjectOffset(int offset,
5680 Representation representation = Representation::Tagged()); 5636 Representation representation = Representation::Tagged());
5681 5637
5682 // Create an access to an in-object property in a JSArray. 5638 // Create an access to an in-object property in a JSArray.
5683 static HObjectAccess ForJSArrayOffset(int offset); 5639 static HObjectAccess ForJSArrayOffset(int offset);
5684 5640
(...skipping 18 matching lines...) Expand all
5703 void SetGVNFlags(HValue *instr, bool is_store); 5659 void SetGVNFlags(HValue *instr, bool is_store);
5704 5660
5705 private: 5661 private:
5706 // internal use only; different parts of an object or array 5662 // internal use only; different parts of an object or array
5707 enum Portion { 5663 enum Portion {
5708 kMaps, // map of an object 5664 kMaps, // map of an object
5709 kArrayLengths, // the length of an array 5665 kArrayLengths, // the length of an array
5710 kElementsPointer, // elements pointer 5666 kElementsPointer, // elements pointer
5711 kBackingStore, // some field in the backing store 5667 kBackingStore, // some field in the backing store
5712 kDouble, // some double field 5668 kDouble, // some double field
5713 kInobject, // some other in-object field 5669 kInobject // some other in-object field
5714 kExternalMemory // some field in external memory
5715 }; 5670 };
5716 5671
5717 HObjectAccess(Portion portion, int offset, 5672 HObjectAccess(Portion portion, int offset,
5718 Representation representation = Representation::Tagged(), 5673 Representation representation = Representation::Tagged(),
5719 Handle<String> name = Handle<String>::null()) 5674 Handle<String> name = Handle<String>::null())
5720 : value_(PortionField::encode(portion) | 5675 : value_(PortionField::encode(portion) |
5721 RepresentationField::encode(representation.kind()) | 5676 RepresentationField::encode(representation.kind()) |
5722 OffsetField::encode(offset)), 5677 OffsetField::encode(offset)),
5723 name_(name) { 5678 name_(name) {
5724 // assert that the fields decode correctly 5679 // assert that the fields decode correctly
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5782 HValue* typecheck = NULL) 5737 HValue* typecheck = NULL)
5783 : access_(access) { 5738 : access_(access) {
5784 ASSERT(object != NULL); 5739 ASSERT(object != NULL);
5785 SetOperandAt(0, object); 5740 SetOperandAt(0, object);
5786 SetOperandAt(1, typecheck != NULL ? typecheck : object); 5741 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5787 5742
5788 Representation representation = access.representation(); 5743 Representation representation = access.representation();
5789 if (representation.IsSmi()) { 5744 if (representation.IsSmi()) {
5790 set_type(HType::Smi()); 5745 set_type(HType::Smi());
5791 set_representation(representation); 5746 set_representation(representation);
5792 } else if (representation.IsDouble() || 5747 } else if (representation.IsDouble()) {
5793 representation.IsExternal() ||
5794 representation.IsInteger32()) {
5795 set_representation(representation); 5748 set_representation(representation);
5796 } else if (FLAG_track_heap_object_fields && 5749 } else if (FLAG_track_heap_object_fields &&
5797 representation.IsHeapObject()) { 5750 representation.IsHeapObject()) {
5798 set_type(HType::NonPrimitive()); 5751 set_type(HType::NonPrimitive());
5799 set_representation(Representation::Tagged()); 5752 set_representation(Representation::Tagged());
5800 } else { 5753 } else {
5801 set_representation(Representation::Tagged()); 5754 set_representation(Representation::Tagged());
5802 } 5755 }
5803 access.SetGVNFlags(this, false); 5756 access.SetGVNFlags(this, false);
5804 } 5757 }
5805 5758
5806 HValue* object() { return OperandAt(0); } 5759 HValue* object() { return OperandAt(0); }
5807 HValue* typecheck() { 5760 HValue* typecheck() {
5808 ASSERT(HasTypeCheck()); 5761 ASSERT(HasTypeCheck());
5809 return OperandAt(1); 5762 return OperandAt(1);
5810 } 5763 }
5811 5764
5812 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); } 5765 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
5813 HObjectAccess access() const { return access_; } 5766 HObjectAccess access() const { return access_; }
5814 Representation field_representation() const { 5767 Representation field_representation() const {
5815 return access_.representation(); 5768 return access_.representation();
5816 } 5769 }
5817 5770
5818 virtual bool HasEscapingOperandAt(int index) { return false; } 5771 virtual bool HasEscapingOperandAt(int index) { return false; }
5819 virtual Representation RequiredInputRepresentation(int index) { 5772 virtual Representation RequiredInputRepresentation(int index) {
5820 if (index == 0 && access().IsExternalMemory()) {
5821 // object must be external in case of external memory access
5822 return Representation::External();
5823 }
5824 return Representation::Tagged(); 5773 return Representation::Tagged();
5825 } 5774 }
5826 virtual void PrintDataTo(StringStream* stream); 5775 virtual void PrintDataTo(StringStream* stream);
5827 5776
5828 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField) 5777 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
5829 5778
5830 protected: 5779 protected:
5831 virtual bool DataEquals(HValue* other) { 5780 virtual bool DataEquals(HValue* other) {
5832 HLoadNamedField* b = HLoadNamedField::cast(other); 5781 HLoadNamedField* b = HLoadNamedField::cast(other);
5833 return access_.Equals(b->access_); 5782 return access_.Equals(b->access_);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
5987 SetGVNFlag(kDependsOnDoubleArrayElements); 5936 SetGVNFlag(kDependsOnDoubleArrayElements);
5988 } 5937 }
5989 } else { 5938 } else {
5990 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 5939 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5991 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 5940 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5992 set_representation(Representation::Double()); 5941 set_representation(Representation::Double());
5993 } else { 5942 } else {
5994 set_representation(Representation::Integer32()); 5943 set_representation(Representation::Integer32());
5995 } 5944 }
5996 5945
5997 SetGVNFlag(kDependsOnExternalMemory); 5946 SetGVNFlag(kDependsOnSpecializedArrayElements);
5998 // Native code could change the specialized array. 5947 // Native code could change the specialized array.
5999 SetGVNFlag(kDependsOnCalls); 5948 SetGVNFlag(kDependsOnCalls);
6000 } 5949 }
6001 5950
6002 SetFlag(kUseGVN); 5951 SetFlag(kUseGVN);
6003 } 5952 }
6004 5953
6005 bool is_external() const { 5954 bool is_external() const {
6006 return IsExternalArrayElementsKind(elements_kind()); 5955 return IsExternalArrayElementsKind(elements_kind());
6007 } 5956 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
6144 write_barrier_mode_(UPDATE_WRITE_BARRIER) { 6093 write_barrier_mode_(UPDATE_WRITE_BARRIER) {
6145 SetOperandAt(0, obj); 6094 SetOperandAt(0, obj);
6146 SetOperandAt(1, val); 6095 SetOperandAt(1, val);
6147 access.SetGVNFlags(this, true); 6096 access.SetGVNFlags(this, true);
6148 } 6097 }
6149 6098
6150 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6099 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
6151 6100
6152 virtual bool HasEscapingOperandAt(int index) { return index == 1; } 6101 virtual bool HasEscapingOperandAt(int index) { return index == 1; }
6153 virtual Representation RequiredInputRepresentation(int index) { 6102 virtual Representation RequiredInputRepresentation(int index) {
6154 if (index == 0 && access().IsExternalMemory()) { 6103 if (index == 1 && field_representation().IsDouble()) {
6155 // object must be external in case of external memory access 6104 return field_representation();
6156 return Representation::External(); 6105 } else if (index == 1 && field_representation().IsSmi()) {
6157 } else if (index == 1 &&
6158 (field_representation().IsDouble() ||
6159 field_representation().IsSmi() ||
6160 field_representation().IsInteger32())) {
6161 return field_representation(); 6106 return field_representation();
6162 } 6107 }
6163 return Representation::Tagged(); 6108 return Representation::Tagged();
6164 } 6109 }
6165 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6110 virtual void HandleSideEffectDominator(GVNFlag side_effect,
6166 HValue* dominator) { 6111 HValue* dominator) {
6167 ASSERT(side_effect == kChangesNewSpacePromotion); 6112 ASSERT(side_effect == kChangesNewSpacePromotion);
6168 new_space_dominator_ = dominator; 6113 new_space_dominator_ = dominator;
6169 } 6114 }
6170 virtual void PrintDataTo(StringStream* stream); 6115 virtual void PrintDataTo(StringStream* stream);
(...skipping 17 matching lines...) Expand all
6188 transition_ = map; 6133 transition_ = map;
6189 } 6134 }
6190 HValue* new_space_dominator() const { return new_space_dominator_; } 6135 HValue* new_space_dominator() const { return new_space_dominator_; }
6191 6136
6192 bool NeedsWriteBarrier() { 6137 bool NeedsWriteBarrier() {
6193 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || 6138 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
6194 transition_.is_null()); 6139 transition_.is_null());
6195 if (IsSkipWriteBarrier()) return false; 6140 if (IsSkipWriteBarrier()) return false;
6196 if (field_representation().IsDouble()) return false; 6141 if (field_representation().IsDouble()) return false;
6197 if (field_representation().IsSmi()) return false; 6142 if (field_representation().IsSmi()) return false;
6198 if (field_representation().IsInteger32()) return false;
6199 return StoringValueNeedsWriteBarrier(value()) && 6143 return StoringValueNeedsWriteBarrier(value()) &&
6200 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6144 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6201 } 6145 }
6202 6146
6203 bool NeedsWriteBarrierForMap() { 6147 bool NeedsWriteBarrierForMap() {
6204 if (IsSkipWriteBarrier()) return false; 6148 if (IsSkipWriteBarrier()) return false;
6205 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); 6149 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
6206 } 6150 }
6207 6151
6208 virtual void FinalizeUniqueValueId() { 6152 virtual void FinalizeUniqueValueId() {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6269 new_space_dominator_(NULL) { 6213 new_space_dominator_(NULL) {
6270 SetOperandAt(0, obj); 6214 SetOperandAt(0, obj);
6271 SetOperandAt(1, key); 6215 SetOperandAt(1, key);
6272 SetOperandAt(2, val); 6216 SetOperandAt(2, val);
6273 6217
6274 if (IsFastObjectElementsKind(elements_kind)) { 6218 if (IsFastObjectElementsKind(elements_kind)) {
6275 SetFlag(kTrackSideEffectDominators); 6219 SetFlag(kTrackSideEffectDominators);
6276 SetGVNFlag(kDependsOnNewSpacePromotion); 6220 SetGVNFlag(kDependsOnNewSpacePromotion);
6277 } 6221 }
6278 if (is_external()) { 6222 if (is_external()) {
6279 SetGVNFlag(kChangesExternalMemory); 6223 SetGVNFlag(kChangesSpecializedArrayElements);
6280 SetFlag(kAllowUndefinedAsNaN); 6224 SetFlag(kAllowUndefinedAsNaN);
6281 } else if (IsFastDoubleElementsKind(elements_kind)) { 6225 } else if (IsFastDoubleElementsKind(elements_kind)) {
6282 SetGVNFlag(kChangesDoubleArrayElements); 6226 SetGVNFlag(kChangesDoubleArrayElements);
6283 } else if (IsFastSmiElementsKind(elements_kind)) { 6227 } else if (IsFastSmiElementsKind(elements_kind)) {
6284 SetGVNFlag(kChangesArrayElements); 6228 SetGVNFlag(kChangesArrayElements);
6285 } else { 6229 } else {
6286 SetGVNFlag(kChangesArrayElements); 6230 SetGVNFlag(kChangesArrayElements);
6287 } 6231 }
6288 6232
6289 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 6233 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
6520 6464
6521 private: 6465 private:
6522 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) 6466 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags)
6523 : HBinaryOperation(context, left, right), flags_(flags) { 6467 : HBinaryOperation(context, left, right), flags_(flags) {
6524 set_representation(Representation::Tagged()); 6468 set_representation(Representation::Tagged());
6525 SetFlag(kUseGVN); 6469 SetFlag(kUseGVN);
6526 SetGVNFlag(kDependsOnMaps); 6470 SetGVNFlag(kDependsOnMaps);
6527 SetGVNFlag(kChangesNewSpacePromotion); 6471 SetGVNFlag(kChangesNewSpacePromotion);
6528 } 6472 }
6529 6473
6530 // No side-effects except possible allocation. 6474 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
6531 // NOTE: this instruction _does not_ call ToString() on its inputs. 6475 // virtual bool IsDeletable() const { return true; }
6532 virtual bool IsDeletable() const { return true; }
6533 6476
6534 const StringAddFlags flags_; 6477 const StringAddFlags flags_;
6535 }; 6478 };
6536 6479
6537 6480
6538 class HStringCharCodeAt: public HTemplateInstruction<3> { 6481 class HStringCharCodeAt: public HTemplateInstruction<3> {
6539 public: 6482 public:
6540 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 6483 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
6541 SetOperandAt(0, context); 6484 SetOperandAt(0, context);
6542 SetOperandAt(1, string); 6485 SetOperandAt(1, string);
6543 SetOperandAt(2, index); 6486 SetOperandAt(2, index);
6544 set_representation(Representation::Integer32()); 6487 set_representation(Representation::Integer32());
6545 SetFlag(kUseGVN); 6488 SetFlag(kUseGVN);
6546 SetGVNFlag(kDependsOnMaps); 6489 SetGVNFlag(kDependsOnMaps);
6547 SetGVNFlag(kChangesNewSpacePromotion); 6490 SetGVNFlag(kChangesNewSpacePromotion);
6548 } 6491 }
6549 6492
6550 virtual Representation RequiredInputRepresentation(int index) { 6493 virtual Representation RequiredInputRepresentation(int index) {
6551 // The index is supposed to be Integer32. 6494 // The index is supposed to be Integer32.
6552 return index == 2 6495 return index == 2
6553 ? Representation::Integer32() 6496 ? Representation::Integer32()
6554 : Representation::Tagged(); 6497 : Representation::Tagged();
6555 } 6498 }
6556 6499
6557 HValue* context() const { return OperandAt(0); } 6500 HValue* context() { return OperandAt(0); }
6558 HValue* string() const { return OperandAt(1); } 6501 HValue* string() { return OperandAt(1); }
6559 HValue* index() const { return OperandAt(2); } 6502 HValue* index() { return OperandAt(2); }
6560 6503
6561 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) 6504 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
6562 6505
6563 protected: 6506 protected:
6564 virtual bool DataEquals(HValue* other) { return true; } 6507 virtual bool DataEquals(HValue* other) { return true; }
6565 6508
6566 virtual Range* InferRange(Zone* zone) { 6509 virtual Range* InferRange(Zone* zone) {
6567 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 6510 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
6568 } 6511 }
6569 6512
6570 private: 6513 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
6571 // No side effects: runtime function assumes string + number inputs. 6514 // private:
6572 virtual bool IsDeletable() const { return true; } 6515 // virtual bool IsDeletable() const { return true; }
6573 }; 6516 };
6574 6517
6575 6518
6576 class HStringCharFromCode: public HTemplateInstruction<2> { 6519 class HStringCharFromCode: public HTemplateInstruction<2> {
6577 public: 6520 public:
6578 static HInstruction* New(Zone* zone, 6521 static HInstruction* New(Zone* zone,
6579 HValue* context, 6522 HValue* context,
6580 HValue* char_code); 6523 HValue* char_code);
6581 6524
6582 virtual Representation RequiredInputRepresentation(int index) { 6525 virtual Representation RequiredInputRepresentation(int index) {
6583 return index == 0 6526 return index == 0
6584 ? Representation::Tagged() 6527 ? Representation::Tagged()
6585 : Representation::Integer32(); 6528 : Representation::Integer32();
6586 } 6529 }
6587 virtual HType CalculateInferredType() { return HType::String(); } 6530 virtual HType CalculateInferredType();
6588 6531
6589 HValue* context() const { return OperandAt(0); } 6532 HValue* context() { return OperandAt(0); }
6590 HValue* value() const { return OperandAt(1); } 6533 HValue* value() { return OperandAt(1); }
6591 6534
6592 virtual bool DataEquals(HValue* other) { return true; } 6535 virtual bool DataEquals(HValue* other) { return true; }
6593 6536
6594 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) 6537 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
6595 6538
6596 private: 6539 private:
6597 HStringCharFromCode(HValue* context, HValue* char_code) { 6540 HStringCharFromCode(HValue* context, HValue* char_code) {
6598 SetOperandAt(0, context); 6541 SetOperandAt(0, context);
6599 SetOperandAt(1, char_code); 6542 SetOperandAt(1, char_code);
6600 set_representation(Representation::Tagged()); 6543 set_representation(Representation::Tagged());
6601 SetFlag(kUseGVN); 6544 SetFlag(kUseGVN);
6602 SetGVNFlag(kChangesNewSpacePromotion); 6545 SetGVNFlag(kChangesNewSpacePromotion);
6603 } 6546 }
6604 6547
6605 virtual bool IsDeletable() const { 6548 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
6606 return !value()->ToNumberCanBeObserved(); 6549 // virtual bool IsDeletable() const { return true; }
6607 }
6608 }; 6550 };
6609 6551
6610 6552
6611 class HStringLength: public HUnaryOperation { 6553 class HStringLength: public HUnaryOperation {
6612 public: 6554 public:
6613 static HInstruction* New(Zone* zone, HValue* string); 6555 static HInstruction* New(Zone* zone, HValue* string);
6614 6556
6615 virtual Representation RequiredInputRepresentation(int index) { 6557 virtual Representation RequiredInputRepresentation(int index) {
6616 return Representation::Tagged(); 6558 return Representation::Tagged();
6617 } 6559 }
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
7006 virtual bool IsDeletable() const { return true; } 6948 virtual bool IsDeletable() const { return true; }
7007 }; 6949 };
7008 6950
7009 6951
7010 #undef DECLARE_INSTRUCTION 6952 #undef DECLARE_INSTRUCTION
7011 #undef DECLARE_CONCRETE_INSTRUCTION 6953 #undef DECLARE_CONCRETE_INSTRUCTION
7012 6954
7013 } } // namespace v8::internal 6955 } } // namespace v8::internal
7014 6956
7015 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6957 #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