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 @@
# include <windows.h>
#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 {
const Config::Edit Config::Edit::None = {};
......@@ -104,9 +110,14 @@ void Variable::UnmaterializedVariables::materializeAll()
variables.clear();
}
Variable::Variable()
Variable::Variable(int arraySize)
: arraySize(arraySize)
{
#if REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
materialize();
#else
unmaterializedVariables->add(this);
#endif
}
Variable::~Variable()
......@@ -118,7 +129,7 @@ void Variable::materialize() const
{
if(!address)
{
address = allocate();
address = Nucleus::allocateStackVariable(getType(), arraySize);
RR_DEBUG_INFO_EMIT_VAR(address);
if(rvalue)
......@@ -169,11 +180,6 @@ Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const
return Nucleus::createGEP(getBaseAddress(), getType(), index, unsignedIndex);
}
Value *Variable::allocate() const
{
return Nucleus::allocateStackVariable(getType());
}
void Variable::materializeAll()
{
unmaterializedVariables->materializeAll();
......
......@@ -119,6 +119,7 @@ class Variable
{
friend class Nucleus;
Variable() = delete;
Variable &operator=(const Variable &) = delete;
public:
......@@ -131,13 +132,14 @@ public:
Value *getElementPointer(Value *index, bool unsignedIndex) const;
virtual Type *getType() const = 0;
int getArraySize() const { return arraySize; }
// This function is only public for testing purposes, as it affects performance.
// It is not considered part of Reactor's public API.
static void materializeAll();
protected:
Variable();
Variable(int arraySize);
Variable(const Variable &) = default;
virtual ~Variable();
......@@ -145,8 +147,6 @@ protected:
private:
static void killUnmaterialized();
virtual Value *allocate() const;
// Set of variables that do not have a stack location yet.
class UnmaterializedVariables
{
......@@ -165,6 +165,7 @@ private:
// for destructing objects at exit. See crbug.com/1074222
static thread_local UnmaterializedVariables *unmaterializedVariables;
const int arraySize;
mutable Value *rvalue = nullptr;
mutable Value *address = nullptr;
};
......@@ -173,7 +174,7 @@ template<class T>
class LValue : public Variable
{
public:
LValue();
LValue(int arraySize = 0);
RValue<Pointer<T>> operator&();
......@@ -2548,11 +2549,6 @@ public:
// self() returns the this pointer to this Array object.
// This function exists because operator&() is overloaded by LValue<T>.
inline Array *self() { return this; }
private:
Value *allocate() const override;
const int arraySize;
};
// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
......@@ -2661,7 +2657,8 @@ RValue<Long> Ticks();
namespace rr {
template<class T>
LValue<T>::LValue()
LValue<T>::LValue(int arraySize)
: Variable(arraySize)
{
#ifdef ENABLE_RR_DEBUG_INFO
materialize();
......@@ -3060,20 +3057,14 @@ Type *Pointer<T>::type()
template<class T, int S>
Array<T, S>::Array(int size)
: arraySize(size)
{
}
template<class T, int S>
Value *Array<T, S>::allocate() const
: LValue<T>(size)
{
return Nucleus::allocateStackVariable(T::type(), arraySize);
}
template<class T, int S>
Reference<T> Array<T, S>::operator[](int index)
{
assert(index < arraySize);
assert(index < Variable::getArraySize());
Value *element = this->getElementPointer(Nucleus::createConstantInt(index), false);
return Reference<T>(element);
......@@ -3082,7 +3073,7 @@ Reference<T> Array<T, S>::operator[](int index)
template<class T, int S>
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);
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