Fix overflow in failure "requested size" field.

Review URL: http://codereview.chromium.org/275016


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3059 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2009-10-14 09:26:16 +00:00
parent a7c0c6e5c4
commit c8b0f822ee
3 changed files with 21 additions and 19 deletions

View File

@ -778,7 +778,7 @@ int Failure::requested() const {
kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits; kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
STATIC_ASSERT(kShiftBits >= 0); STATIC_ASSERT(kShiftBits >= 0);
ASSERT(type() == RETRY_AFTER_GC); ASSERT(type() == RETRY_AFTER_GC);
return value() >> kShiftBits; return static_cast<int>(value() >> kShiftBits);
} }
@ -804,29 +804,31 @@ Failure* Failure::OutOfMemoryException() {
} }
int Failure::value() const { intptr_t Failure::value() const {
return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kFailureTagSize); return reinterpret_cast<intptr_t>(this) >> kFailureTagSize;
} }
Failure* Failure::RetryAfterGC(int requested_bytes) { Failure* Failure::RetryAfterGC(int requested_bytes) {
// Assert that the space encoding fits in the three bytes allotted for it. // Assert that the space encoding fits in the three bytes allotted for it.
ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0); ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
int requested = requested_bytes >> kObjectAlignmentBits; intptr_t requested = requested_bytes >> kObjectAlignmentBits;
int tag_bits = kSpaceTagSize + kFailureTypeTagSize;
if (((requested << tag_bits) >> tag_bits) != requested) {
// No room for entire requested size in the bits. Round down to
// maximally representable size.
requested = static_cast<intptr_t>(
(~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
}
int value = (requested << kSpaceTagSize) | NEW_SPACE; int value = (requested << kSpaceTagSize) | NEW_SPACE;
ASSERT(value >> kSpaceTagSize == requested);
ASSERT(Smi::IsValid(value));
ASSERT(value == ((value << kFailureTypeTagSize) >> kFailureTypeTagSize));
ASSERT(Smi::IsValid(value << kFailureTypeTagSize));
return Construct(RETRY_AFTER_GC, value); return Construct(RETRY_AFTER_GC, value);
} }
Failure* Failure::Construct(Type type, int value) { Failure* Failure::Construct(Type type, intptr_t value) {
int info = (value << kFailureTypeTagSize) | type; intptr_t info = (static_cast<intptr_t>(value) << kFailureTypeTagSize) | type;
ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info); ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
return reinterpret_cast<Failure*>( return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
(static_cast<intptr_t>(info) << kFailureTagSize) | kFailureTag);
} }

View File

@ -618,12 +618,12 @@ void Smi::SmiPrint(StringStream* accumulator) {
void Failure::FailurePrint(StringStream* accumulator) { void Failure::FailurePrint(StringStream* accumulator) {
accumulator->Add("Failure(%d)", value()); accumulator->Add("Failure(%p)", reinterpret_cast<void*>(value()));
} }
void Failure::FailurePrint() { void Failure::FailurePrint() {
PrintF("Failure(%d)", value()); PrintF("Failure(%p)", reinterpret_cast<void*>(value()));
} }

View File

@ -948,10 +948,10 @@ class Smi: public Object {
// //
// Failures are a single word, encoded as follows: // Failures are a single word, encoded as follows:
// +-------------------------+---+--+--+ // +-------------------------+---+--+--+
// |rrrrrrrrrrrrrrrrrrrrrrrrr|sss|tt|11| // |...rrrrrrrrrrrrrrrrrrrrrr|sss|tt|11|
// +-------------------------+---+--+--+ // +-------------------------+---+--+--+
// 3 7 6 4 32 10 // 7 6 4 32 10
// 1 //
// //
// The low two bits, 0-1, are the failure tag, 11. The next two bits, // The low two bits, 0-1, are the failure tag, 11. The next two bits,
// 2-3, are a failure type tag 'tt' with possible values: // 2-3, are a failure type tag 'tt' with possible values:
@ -1013,8 +1013,8 @@ class Failure: public Object {
#endif #endif
private: private:
inline int value() const; inline intptr_t value() const;
static inline Failure* Construct(Type type, int value = 0); static inline Failure* Construct(Type type, intptr_t value = 0);
DISALLOW_IMPLICIT_CONSTRUCTORS(Failure); DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
}; };