Fix for bug 429168, PdfJs regression. We pay a very high cost for...

Fix for bug 429168, PdfJs regression. We pay a very high cost for AllocationResult being a > kPointerSize struct. This can be avoided by using Smis to indicate failure with retry spaces.

BUG=429168
LOG=N
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/699473002

Cr-Commit-Position: refs/heads/master@{#25057}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25057 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 310000ae
...@@ -376,7 +376,6 @@ enum AllocationSpace { ...@@ -376,7 +376,6 @@ enum AllocationSpace {
CELL_SPACE, // Only and all cell objects. CELL_SPACE, // Only and all cell objects.
PROPERTY_CELL_SPACE, // Only and all global property cell objects. PROPERTY_CELL_SPACE, // Only and all global property cell objects.
LO_SPACE, // Promoted large objects. LO_SPACE, // Promoted large objects.
INVALID_SPACE, // Only used in AllocationResult to signal success.
FIRST_SPACE = NEW_SPACE, FIRST_SPACE = NEW_SPACE,
LAST_SPACE = LO_SPACE, LAST_SPACE = LO_SPACE,
......
...@@ -458,8 +458,6 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) { ...@@ -458,8 +458,6 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
case PROPERTY_CELL_SPACE: case PROPERTY_CELL_SPACE:
case LO_SPACE: case LO_SPACE:
return false; return false;
case INVALID_SPACE:
break;
} }
UNREACHABLE(); UNREACHABLE();
return false; return false;
......
...@@ -4545,8 +4545,6 @@ bool Heap::InSpace(Address addr, AllocationSpace space) { ...@@ -4545,8 +4545,6 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
return property_cell_space_->Contains(addr); return property_cell_space_->Contains(addr);
case LO_SPACE: case LO_SPACE:
return lo_space_->SlowContains(addr); return lo_space_->SlowContains(addr);
case INVALID_SPACE:
break;
} }
UNREACHABLE(); UNREACHABLE();
return false; return false;
......
...@@ -1614,16 +1614,19 @@ class AllocationResult { ...@@ -1614,16 +1614,19 @@ class AllocationResult {
public: public:
// Implicit constructor from Object*. // Implicit constructor from Object*.
AllocationResult(Object* object) // NOLINT AllocationResult(Object* object) // NOLINT
: object_(object), : object_(object) {
retry_space_(INVALID_SPACE) {} // AllocationResults can't return Smis, which are used to represent
// failure and the space to retry in.
CHECK(!object->IsSmi());
}
AllocationResult() : object_(NULL), retry_space_(INVALID_SPACE) {} AllocationResult() : object_(Smi::FromInt(NEW_SPACE)) {}
static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) { static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
return AllocationResult(space); return AllocationResult(space);
} }
inline bool IsRetry() { return retry_space_ != INVALID_SPACE; } inline bool IsRetry() { return object_->IsSmi(); }
template <typename T> template <typename T>
bool To(T** obj) { bool To(T** obj) {
...@@ -1639,18 +1642,20 @@ class AllocationResult { ...@@ -1639,18 +1642,20 @@ class AllocationResult {
AllocationSpace RetrySpace() { AllocationSpace RetrySpace() {
DCHECK(IsRetry()); DCHECK(IsRetry());
return retry_space_; return static_cast<AllocationSpace>(Smi::cast(object_)->value());
} }
private: private:
explicit AllocationResult(AllocationSpace space) explicit AllocationResult(AllocationSpace space)
: object_(NULL), retry_space_(space) {} : object_(Smi::FromInt(static_cast<int>(space))) {}
Object* object_; Object* object_;
AllocationSpace retry_space_;
}; };
STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
class PagedSpace : public Space { class PagedSpace : public Space {
public: public:
// Creates a space with a maximum capacity, and an id. // Creates a space with a maximum capacity, and an id.
......
...@@ -1903,7 +1903,7 @@ AllocationSpace Serializer::SpaceOfObject(HeapObject* object) { ...@@ -1903,7 +1903,7 @@ AllocationSpace Serializer::SpaceOfObject(HeapObject* object) {
} }
} }
UNREACHABLE(); UNREACHABLE();
return INVALID_SPACE; return FIRST_SPACE;
} }
......
...@@ -296,7 +296,7 @@ class SerializerDeserializer: public ObjectVisitor { ...@@ -296,7 +296,7 @@ class SerializerDeserializer: public ObjectVisitor {
// No reservation for large object space necessary. // No reservation for large object space necessary.
static const int kNumberOfPreallocatedSpaces = LO_SPACE; static const int kNumberOfPreallocatedSpaces = LO_SPACE;
static const int kNumberOfSpaces = INVALID_SPACE; static const int kNumberOfSpaces = LAST_SPACE + 1;
protected: protected:
// Where the pointed-to object can be found: // Where the pointed-to object can be found:
......
...@@ -86,7 +86,7 @@ static AllocationResult AllocateAfterFailures() { ...@@ -86,7 +86,7 @@ static AllocationResult AllocateAfterFailures() {
Builtins::kIllegal)).ToObjectChecked(); Builtins::kIllegal)).ToObjectChecked();
// Return success. // Return success.
return Smi::FromInt(42); return heap->true_value();
} }
...@@ -100,7 +100,7 @@ TEST(StressHandles) { ...@@ -100,7 +100,7 @@ TEST(StressHandles) {
v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate()); v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate());
env->Enter(); env->Enter();
Handle<Object> o = Test(); Handle<Object> o = Test();
CHECK(o->IsSmi() && Smi::cast(*o)->value() == 42); CHECK(o->IsTrue());
env->Exit(); env->Exit();
} }
...@@ -162,7 +162,7 @@ TEST(StressJS) { ...@@ -162,7 +162,7 @@ TEST(StressJS) {
// Call the accessor through JavaScript. // Call the accessor through JavaScript.
v8::Handle<v8::Value> result = v8::Script::Compile( v8::Handle<v8::Value> result = v8::Script::Compile(
v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run(); v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run();
CHECK_EQ(42, result->Int32Value()); CHECK_EQ(true, result->BooleanValue());
env->Exit(); env->Exit();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment