[poincare] Fix Function::size()

This commit is contained in:
Léa Saviot
2018-10-04 15:48:14 +02:00
committed by Émilie Feral
parent 30e92a87c7
commit aebeeda171
4 changed files with 33 additions and 17 deletions

View File

@@ -9,7 +9,7 @@ namespace Poincare {
class FunctionNode : public SymbolNode {
public:
// TreeNode
size_t size() const override { return sizeof(FunctionNode); }
size_t size() const override;
int numberOfChildren() const override { return 1; } //TODO allow any number of children? Needs templating
#if POINCARE_TREE_LOG
virtual void logNodeName(std::ostream & stream) const override {

View File

@@ -8,6 +8,15 @@ namespace Poincare {
/* TODO: should we keep the size of SymbolNode as a member to speed up TreePool
* scan? */
/* Symbol Node contains an empty member variable "m_name", which is used to get
* the string that follows. This means that a SymbolNode's size is sizeo
* (SymbolNode) + strlen(string).
*
* Seen by TreePool: |SymbolNode |
* SymbolNode layout: |ExpressionNode|m_name| |
* Memory content: |ExpressionNode|S |y|m|b|o|l|N|a|m|e|0|
* */
class SymbolNode final : public ExpressionNode {
friend class Store;
public:
@@ -54,11 +63,11 @@ public:
bool isPi() const { return isSymbolChar(Ion::Charset::SmallPi); }
bool isExponential() const { return isSymbolChar(Ion::Charset::Exponential); }
bool isIComplex() const { return isSymbolChar(Ion::Charset::IComplex); }
protected:
char m_name[0]; // MUST be the last member variable
private:
template<typename T> Evaluation<T> templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
bool isSymbolChar(char c) const { const char symbolName[2] = {c, 0}; return strcmp(m_name, symbolName) == 0; }
char m_name[0];
};
class Symbol final : public Expression {

View File

@@ -1,4 +1,5 @@
#include <poincare/function.h>
#include <poincare/helpers.h>
#include <poincare/layout_helper.h>
#include <poincare/parenthesis.h>
#include <poincare/rational.h>
@@ -8,6 +9,16 @@
namespace Poincare {
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
* node moves faster.*/
static size_t NodeSize(size_t nameLength) {
return Helpers::AlignedSize(sizeof(FunctionNode)+nameLength+1, 4);
}
size_t FunctionNode::size() const {
return NodeSize(strlen(m_name));
}
Expression FunctionNode::replaceSymbolWithExpression(const Symbol & symbol, const Expression & expression) {
return Function(this).replaceSymbolWithExpression(symbol, expression);
}
@@ -87,7 +98,7 @@ Evaluation<double> FunctionNode::approximate(DoublePrecision p, Context& context
}
Function::Function(const char * name) :
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>())
Function(TreePool::sharedPool()->createTreeNode<FunctionNode>(NodeSize(strlen(name))))
{
static_cast<FunctionNode *>(Expression::node())->setName(name, strlen(name));
}

View File

@@ -1,10 +1,11 @@
#include <poincare/symbol.h>
#include <poincare/context.h>
#include <poincare/rational.h>
#include <poincare/parenthesis.h>
#include <poincare/layout_helper.h>
#include <poincare/char_layout.h>
#include <poincare/context.h>
#include <poincare/helpers.h>
#include <poincare/horizontal_layout.h>
#include <poincare/layout_helper.h>
#include <poincare/parenthesis.h>
#include <poincare/rational.h>
#include <poincare/vertical_offset_layout.h>
#include <ion.h>
#include <cmath>
@@ -16,17 +17,12 @@ constexpr char Symbol::k_ans[];
/* TreePool uses adresses and sizes that are multiples of 4 in order to make
* node moves faster.*/
size_t SymbolSize(size_t nameLength) {
size_t realSize = sizeof(SymbolNode)+nameLength+1;
size_t alignment = 4;
size_t modulo = realSize % alignment;
size_t result = realSize + (modulo == 0 ? 0 : alignment - modulo);
assert(result % 4 == 0);
return result;
static size_t NodeSize(size_t nameLength) {
return Helpers::AlignedSize(sizeof(SymbolNode)+nameLength+1, 4);
}
size_t SymbolNode::size() const {
return SymbolSize(strlen(m_name));
return NodeSize(strlen(m_name));
}
ExpressionNode::Sign SymbolNode::sign() const {
@@ -166,7 +162,7 @@ Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::An
return e.approximateToEvaluation<T>(context, angleUnit);
}
Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode<SymbolNode>(SymbolSize(length))) {
Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode<SymbolNode>(NodeSize(length))) {
node()->setName(name, length);
}