Commit 84c61e18 by Antonio Maiorano

Fix crash from rr::Array with ENABLE_RR_DEBUG_INFO enabled

Fixes crash when using rr::Array with ENABLE_RR_DEBUG_INFO. This is because when the LValue ctor calls materialize, this would end up calling the virtual allocate() function, which would not call the overridden version in rr::Array as it was not fully constructed yet. Instead, we go back to having the size stored in Value, and passing it up the constructor chain. Note that this effectively reverts "Eliminate the array size from rr::Variable" (5e16bc45) with some modifications. Bug: b/174160049 Change-Id: I83cec95a74f32ef7276ed60f979a4c32f571eb8a Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/50809 Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 95ffe036
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
# include <windows.h> # include <windows.h>
#endif #endif
// Define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION to non-zero to ensure all
// variables have a stack location obtained throuch alloca().
#ifndef REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
# define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION 0
#endif
namespace rr { namespace rr {
const Config::Edit Config::Edit::None = {}; const Config::Edit Config::Edit::None = {};
...@@ -104,9 +110,14 @@ void Variable::UnmaterializedVariables::materializeAll() ...@@ -104,9 +110,14 @@ void Variable::UnmaterializedVariables::materializeAll()
variables.clear(); variables.clear();
} }
Variable::Variable() Variable::Variable(int arraySize)
: arraySize(arraySize)
{ {
#if REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
materialize();
#else
unmaterializedVariables->add(this); unmaterializedVariables->add(this);
#endif
} }
Variable::~Variable() Variable::~Variable()
...@@ -118,7 +129,7 @@ void Variable::materialize() const ...@@ -118,7 +129,7 @@ void Variable::materialize() const
{ {
if(!address) if(!address)
{ {
address = allocate(); address = Nucleus::allocateStackVariable(getType(), arraySize);
RR_DEBUG_INFO_EMIT_VAR(address); RR_DEBUG_INFO_EMIT_VAR(address);
if(rvalue) if(rvalue)
...@@ -169,11 +180,6 @@ Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const ...@@ -169,11 +180,6 @@ Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const
return Nucleus::createGEP(getBaseAddress(), getType(), index, unsignedIndex); return Nucleus::createGEP(getBaseAddress(), getType(), index, unsignedIndex);
} }
Value *Variable::allocate() const
{
return Nucleus::allocateStackVariable(getType());
}
void Variable::materializeAll() void Variable::materializeAll()
{ {
unmaterializedVariables->materializeAll(); unmaterializedVariables->materializeAll();
......
...@@ -119,6 +119,7 @@ class Variable ...@@ -119,6 +119,7 @@ class Variable
{ {
friend class Nucleus; friend class Nucleus;
Variable() = delete;
Variable &operator=(const Variable &) = delete; Variable &operator=(const Variable &) = delete;
public: public:
...@@ -131,13 +132,14 @@ public: ...@@ -131,13 +132,14 @@ public:
Value *getElementPointer(Value *index, bool unsignedIndex) const; Value *getElementPointer(Value *index, bool unsignedIndex) const;
virtual Type *getType() const = 0; virtual Type *getType() const = 0;
int getArraySize() const { return arraySize; }
// This function is only public for testing purposes, as it affects performance. // This function is only public for testing purposes, as it affects performance.
// It is not considered part of Reactor's public API. // It is not considered part of Reactor's public API.
static void materializeAll(); static void materializeAll();
protected: protected:
Variable(); Variable(int arraySize);
Variable(const Variable &) = default; Variable(const Variable &) = default;
virtual ~Variable(); virtual ~Variable();
...@@ -145,8 +147,6 @@ protected: ...@@ -145,8 +147,6 @@ protected:
private: private:
static void killUnmaterialized(); static void killUnmaterialized();
virtual Value *allocate() const;
// Set of variables that do not have a stack location yet. // Set of variables that do not have a stack location yet.
class UnmaterializedVariables class UnmaterializedVariables
{ {
...@@ -165,6 +165,7 @@ private: ...@@ -165,6 +165,7 @@ private:
// for destructing objects at exit. See crbug.com/1074222 // for destructing objects at exit. See crbug.com/1074222
static thread_local UnmaterializedVariables *unmaterializedVariables; static thread_local UnmaterializedVariables *unmaterializedVariables;
const int arraySize;
mutable Value *rvalue = nullptr; mutable Value *rvalue = nullptr;
mutable Value *address = nullptr; mutable Value *address = nullptr;
}; };
...@@ -173,7 +174,7 @@ template<class T> ...@@ -173,7 +174,7 @@ template<class T>
class LValue : public Variable class LValue : public Variable
{ {
public: public:
LValue(); LValue(int arraySize = 0);
RValue<Pointer<T>> operator&(); RValue<Pointer<T>> operator&();
...@@ -2548,11 +2549,6 @@ public: ...@@ -2548,11 +2549,6 @@ public:
// self() returns the this pointer to this Array object. // self() returns the this pointer to this Array object.
// This function exists because operator&() is overloaded by LValue<T>. // This function exists because operator&() is overloaded by LValue<T>.
inline Array *self() { return this; } inline Array *self() { return this; }
private:
Value *allocate() const override;
const int arraySize;
}; };
// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment // RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
...@@ -2661,7 +2657,8 @@ RValue<Long> Ticks(); ...@@ -2661,7 +2657,8 @@ RValue<Long> Ticks();
namespace rr { namespace rr {
template<class T> template<class T>
LValue<T>::LValue() LValue<T>::LValue(int arraySize)
: Variable(arraySize)
{ {
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
materialize(); materialize();
...@@ -3060,20 +3057,14 @@ Type *Pointer<T>::type() ...@@ -3060,20 +3057,14 @@ Type *Pointer<T>::type()
template<class T, int S> template<class T, int S>
Array<T, S>::Array(int size) Array<T, S>::Array(int size)
: arraySize(size) : LValue<T>(size)
{
}
template<class T, int S>
Value *Array<T, S>::allocate() const
{ {
return Nucleus::allocateStackVariable(T::type(), arraySize);
} }
template<class T, int S> template<class T, int S>
Reference<T> Array<T, S>::operator[](int index) Reference<T> Array<T, S>::operator[](int index)
{ {
assert(index < arraySize); assert(index < Variable::getArraySize());
Value *element = this->getElementPointer(Nucleus::createConstantInt(index), false); Value *element = this->getElementPointer(Nucleus::createConstantInt(index), false);
return Reference<T>(element); return Reference<T>(element);
...@@ -3082,7 +3073,7 @@ Reference<T> Array<T, S>::operator[](int index) ...@@ -3082,7 +3073,7 @@ Reference<T> Array<T, S>::operator[](int index)
template<class T, int S> template<class T, int S>
Reference<T> Array<T, S>::operator[](unsigned int index) Reference<T> Array<T, S>::operator[](unsigned int index)
{ {
assert(index < static_cast<unsigned int>(arraySize)); assert(index < static_cast<unsigned int>(Variable::getArraySize()));
Value *element = this->getElementPointer(Nucleus::createConstantInt(index), true); Value *element = this->getElementPointer(Nucleus::createConstantInt(index), true);
return Reference<T>(element); return Reference<T>(element);
......
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