Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

18652: Improves performance by reducing lock contention via immediate return values, fixes rare bugs #47

Merged
merged 61 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
e2af5e5
18652: Begins implementation of immediate return types for interpret …
howsohazard Dec 13, 2023
4b716a0
18652: Refactors EvaluableNodeReference access
howsohazard Dec 13, 2023
568797c
18652: Undoes check-in of out.txt
howsohazard Dec 13, 2023
3e15b33
18652: EvaluableNodeReference can now return immediate values
howsohazard Dec 13, 2023
a8d0dcd
18652: Removes unnecessary overhead layer
howsohazard Dec 13, 2023
5762840
18652: Begins implementation of immediate value return types
howsohazard Dec 13, 2023
c7a6672
18652: Begins implementing immediate return values
howsohazard Dec 13, 2023
ca6566c
18652: More immediate implementation
howsohazard Dec 13, 2023
e995c42
18652: Code cleanup
howsohazard Dec 13, 2023
22ba863
18652: Adds todos
howsohazard Dec 13, 2023
72a0903
18652: Removes todo
howsohazard Dec 15, 2023
15a2008
Merge branch 'main' into 18652-interpret-node-immediate
howsohazard Dec 15, 2023
144d83f
18652: More implementation
howsohazard Dec 16, 2023
91bd708
Merge branch '18652-interpret-node-immediate' of https://github.com/h…
howsohazard Dec 16, 2023
100ff73
Merge branch 'main' into 18652-interpret-node-immediate
howsohazard Dec 19, 2023
8a55b08
Merge branch 'main' into 18652-interpret-node-immediate
howsohazard Dec 20, 2023
5170191
Merge branch 'main' into 18652-interpret-node-immediate
howsohazard Dec 22, 2023
0a0c497
18652: More implementation
howsohazard Dec 22, 2023
c56e6d8
18652: Todo updates
howsohazard Dec 22, 2023
7c9bfd3
18652: More implementation
howsohazard Dec 22, 2023
ef4f636
18652: More implementation
howsohazard Dec 23, 2023
f17aa72
18652: Updates InterpretNodeIntoBoolValue
howsohazard Dec 23, 2023
ccad4fa
18652: More implementation
howsohazard Dec 23, 2023
53acd93
18652: More implementation
howsohazard Dec 23, 2023
8607ea5
18652: More implementation
howsohazard Dec 23, 2023
7595521
18652: More implementation
howsohazard Dec 23, 2023
88e5623
18652: More implementation
howsohazard Dec 23, 2023
b3733ff
18652: More implementation
howsohazard Dec 23, 2023
b0feaf2
18652: More progress
howsohazard Dec 23, 2023
08ec410
18652: Fixes bug
howsohazard Dec 23, 2023
bb27fdf
18652: Fixes bug with or opcode
howsohazard Dec 24, 2023
555757d
18652: More progress
howsohazard Dec 24, 2023
ef8d854
18652: Adds todo
howsohazard Dec 24, 2023
2413e7b
18652: More memory reuse
howsohazard Dec 24, 2023
f7e4107
18652: More implementation progress
howsohazard Dec 25, 2023
066f558
18652: More progress
howsohazard Dec 25, 2023
98a8e6b
18652: More progress
howsohazard Dec 25, 2023
b05feae
18652: Updates todos
howsohazard Dec 25, 2023
1d7dfae
18652: Adds string id references to immediates
howsohazard Dec 25, 2023
613e7c3
18652: More implementation progress
howsohazard Dec 25, 2023
b771e62
18652: More implementation
howsohazard Dec 25, 2023
7d9ea2e
18652: Fixes resource leak
howsohazard Dec 25, 2023
a35ced5
18652: More implementation
howsohazard Dec 26, 2023
30bf2da
18652: More progress
howsohazard Dec 26, 2023
b0f6362
18652: Implements immediate handling for format opcode
howsohazard Dec 26, 2023
2b93a65
18652: More progress
howsohazard Dec 26, 2023
67476d8
18652: Code cleanup
howsohazard Dec 26, 2023
380d560
18652: More cleanup
howsohazard Dec 26, 2023
a7bfba7
18652: Adds new AllocNode types for strings
howsohazard Dec 26, 2023
8506609
18652: More prep for cleanup
howsohazard Dec 26, 2023
9850f35
18652: More progress
howsohazard Dec 26, 2023
435859f
18652: More implementation progress
howsohazard Dec 26, 2023
6643791
18652: More progress
howsohazard Dec 26, 2023
477e6df
18652: More implementation
howsohazard Dec 26, 2023
07d1ee5
18652: More code reduction
howsohazard Dec 26, 2023
5bd202d
18652: More cleanup
howsohazard Dec 26, 2023
ad02594
18652: Adds space
howsohazard Dec 26, 2023
fdd84e0
18652: Fixes bug
howsohazard Dec 26, 2023
da749a0
18652: Extra cleanup in error handling and less common paths
howsohazard Dec 28, 2023
ab5af38
Merge branch 'main' into 18652-interpret-node-immediate
howsohazard Dec 29, 2023
2d04853
18652: Updates comment
howsohazard Dec 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Amalgam/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ EvaluableNode *Parser::GetCodeForPathFromAToB(UnparseData &upd, EvaluableNode *a

//build code to get the reference
EvaluableNode *refpath = upd.enm->AllocNode(ENT_TARGET);
refpath->AppendOrderedChildNode(upd.enm->AllocNode(a_ancestor_depth));
refpath->AppendOrderedChildNode(upd.enm->AllocNode(static_cast<double>(a_ancestor_depth)));

//combine together
while(b_path_nodes.size() > 0)
Expand Down
4 changes: 2 additions & 2 deletions src/Amalgam/entity/Entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ void Entity::SetRoot(EvaluableNode *_code, bool allocated_with_entity_enm, Evalu
else
{
auto code_copy = evaluableNodeManager.DeepAllocCopy(_code, metadata_modifier);
evaluableNodeManager.SetRootNode(code_copy.reference);
evaluableNodeManager.SetRootNode(code_copy);
}

//keep reference for current root
Expand Down Expand Up @@ -919,7 +919,7 @@ void Entity::SetRoot(EvaluableNode *_code, bool allocated_with_entity_enm, Evalu
void Entity::SetRoot(std::string &code_string, EvaluableNodeManager::EvaluableNodeMetadataModifier metadata_modifier, std::vector<EntityWriteListener *> *write_listeners)
{
EvaluableNodeReference new_code = Parser::Parse(code_string, &evaluableNodeManager);
SetRoot(new_code.reference, true, metadata_modifier, write_listeners);
SetRoot(new_code, true, metadata_modifier, write_listeners);
}

void Entity::AccumRoot(EvaluableNodeReference accum_code, bool allocated_with_entity_enm, EvaluableNodeManager::EvaluableNodeMetadataModifier metadata_modifier, std::vector<EntityWriteListener *> *write_listeners)
Expand Down
12 changes: 6 additions & 6 deletions src/Amalgam/entity/EntityManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Entity *EntityManipulation::EntitiesMergeMethod::MergeValues(Entity *a, Entity *
merged_entity->SetRandomStream(b->GetRandomStream());

//merge entitys' code
EvaluableNode *code_a = (a != nullptr ? a->GetRoot().reference : nullptr);
EvaluableNode *code_b = (b != nullptr ? b->GetRoot().reference : nullptr);
EvaluableNodeReference code_a = (a != nullptr ? a->GetRoot() : EvaluableNodeReference::Null());
EvaluableNodeReference code_b = (b != nullptr ? b->GetRoot() : EvaluableNodeReference::Null());

EvaluableNodeTreeManipulation::NodesMergeMethod mm(&merged_entity->evaluableNodeManager, keepAllOfBoth, true);
EvaluableNode *result = mm.MergeValues(code_a, code_b);
Expand All @@ -44,8 +44,8 @@ Entity *EntityManipulation::EntitiesMergeForDifferenceMethod::MergeValues(Entity
Entity *result = new Entity();

//compare entitys' code
EvaluableNode *code_a = (a != nullptr ? a->GetRoot().reference : nullptr);
EvaluableNode *code_b = (b != nullptr ? b->GetRoot().reference : nullptr);
EvaluableNodeReference code_a = (a != nullptr ? a->GetRoot() : EvaluableNodeReference::Null());
EvaluableNodeReference code_b = (b != nullptr ? b->GetRoot() : EvaluableNodeReference::Null());

if(a != nullptr)
aEntitiesIncludedFromB[b] = a;
Expand Down Expand Up @@ -125,8 +125,8 @@ Entity *EntityManipulation::EntitiesMixMethod::MergeValues(Entity *a, Entity *b,
merged_entity->SetRandomStream(b->GetRandomStream());

//merge entity's code
EvaluableNode *code_a = (a != nullptr ? a->GetRoot().reference : nullptr);
EvaluableNode *code_b = (b != nullptr ? b->GetRoot().reference : nullptr);
EvaluableNodeReference code_a = (a != nullptr ? a->GetRoot() : EvaluableNodeReference::Null());
EvaluableNodeReference code_b = (b != nullptr ? b->GetRoot() : EvaluableNodeReference::Null());

EvaluableNodeTreeManipulation::NodesMixMethod mm(interpreter->randomStream.CreateOtherStreamViaRand(),
&merged_entity->evaluableNodeManager, fractionA, fractionB, similarMixChance);
Expand Down
128 changes: 128 additions & 0 deletions src/Amalgam/evaluablenode/EvaluableNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,15 @@ class EvaluableNodeImmediateValueWithType
: nodeType(ENIVT_NULL)
{ }

__forceinline EvaluableNodeImmediateValueWithType(bool value)
{
nodeType = ENIVT_NUMBER;
if(value)
nodeValue.number = 1.0;
else
nodeValue.number = 0.0;
}

constexpr EvaluableNodeImmediateValueWithType(double number)
: nodeType(ENIVT_NUMBER), nodeValue(number)
{ }
Expand Down Expand Up @@ -1091,6 +1100,125 @@ class EvaluableNodeImmediateValueWithType
nodeValue = EvaluableNodeImmediateValue(en);
}

bool GetValueAsBoolean()
{
if(nodeType == ENIVT_NUMBER)
{
if(nodeValue.number == 0.0)
return false;
if(FastIsNaN(nodeValue.number))
return false;
return true;
}

if(nodeType == ENIVT_STRING_ID)
{
if(nodeValue.stringID <= StringInternPool::EMPTY_STRING_ID)
return false;
return true;
}

if(nodeType == ENIVT_CODE)
return EvaluableNode::IsTrue(nodeValue.code);

//nodeType is one of ENIVT_NOT_EXIST, ENIVT_NULL, ENIVT_NUMBER_INDIRECTION_INDEX
return false;
}

double GetValueAsNumber(double value_if_null = std::numeric_limits<double>::quiet_NaN())
{
if(nodeType == ENIVT_NUMBER)
return nodeValue.number;

if(nodeType == ENIVT_STRING_ID)
{
if(nodeValue.stringID == string_intern_pool.NOT_A_STRING_ID)
return value_if_null;

const auto &str = string_intern_pool.GetStringFromID(nodeValue.stringID);
auto [value, success] = Platform_StringToNumber(str);
if(success)
return value;
return value_if_null;
}

if(nodeType == ENIVT_CODE)
return EvaluableNode::ToNumber(nodeValue.code);

//nodeType is one of ENIVT_NOT_EXIST, ENIVT_NULL, ENIVT_NUMBER_INDIRECTION_INDEX
return value_if_null;
}

std::pair<bool, std::string> GetValueAsString()
{
if(nodeType == ENIVT_NUMBER)
{
if(FastIsNaN(nodeValue.number))
return std::make_pair(false, "");

return std::make_pair(true, EvaluableNode::NumberToString(nodeValue.number));
}

if(nodeType == ENIVT_STRING_ID)
{
if(nodeValue.stringID == string_intern_pool.NOT_A_STRING_ID)
return std::make_pair(false, "");

const auto &str = string_intern_pool.GetStringFromID(nodeValue.stringID);
return std::make_pair(true, str);
}

if(nodeType == ENIVT_CODE)
return std::make_pair(true, EvaluableNode::ToStringPreservingOpcodeType(nodeValue.code));

//nodeType is one of ENIVT_NOT_EXIST, ENIVT_NULL, ENIVT_NUMBER_INDIRECTION_INDEX
return std::make_pair(false, "");
}

StringInternPool::StringID GetValueAsStringIDIfExists()
{
if(nodeType == ENIVT_NUMBER)
{
if(FastIsNaN(nodeValue.number))
return StringInternPool::NOT_A_STRING_ID;

const std::string str_value = EvaluableNode::NumberToString(nodeValue.number);
//will return empty string if not found
return string_intern_pool.GetIDFromString(str_value);
}

if(nodeType == ENIVT_STRING_ID)
return nodeValue.stringID;

if(nodeType == ENIVT_CODE)
return EvaluableNode::ToStringIDIfExists(nodeValue.code);

//nodeType is one of ENIVT_NOT_EXIST, ENIVT_NULL, ENIVT_NUMBER_INDIRECTION_INDEX
return string_intern_pool.NOT_A_STRING_ID;
}

StringInternPool::StringID GetValueAsStringIDWithReference()
{
if(nodeType == ENIVT_NUMBER)
{
if(FastIsNaN(nodeValue.number))
return StringInternPool::NOT_A_STRING_ID;

const std::string str_value = EvaluableNode::NumberToString(nodeValue.number);
//will return empty string if not found
return string_intern_pool.CreateStringReference(str_value);
}

if(nodeType == ENIVT_STRING_ID)
return string_intern_pool.CreateStringReference(nodeValue.stringID);

if(nodeType == ENIVT_CODE)
return EvaluableNode::ToStringIDWithReference(nodeValue.code);

//nodeType is one of ENIVT_NOT_EXIST, ENIVT_NULL, ENIVT_NUMBER_INDIRECTION_INDEX
return string_intern_pool.NOT_A_STRING_ID;
}

static inline bool AreEqual(EvaluableNodeImmediateValueWithType &a, EvaluableNodeImmediateValueWithType &b)
{
return EvaluableNodeImmediateValue::AreEqual(a.nodeType, a.nodeValue, b.nodeType, b.nodeValue);
Expand Down
Loading