Skip to content

Commit 87dc7f3

Browse files
committed
Make the new flag be -prim-hash-check
This allows us to use the flag in CI and check that the hashes are correct. Signed-off-by: Stefan Marr <git@stefan-marr.de>
1 parent 09b8e9c commit 87dc7f3

7 files changed

Lines changed: 55 additions & 26 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ jobs:
6565
run: |
6666
cd cmake-build
6767
./unittests -cp ../Smalltalk:../TestSuite/BasicInterpreterTests ../Examples/Hello.som
68+
./SOM++ -prim-hash-check -cp ../Smalltalk ../Examples/Benchmarks/BenchmarkHarness.som VectorBenchmark 1 1
6869
6970
# - name: Run Integration Tests
7071
# run: |

.gitlab-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ build_and_test:
7979
- make -j
8080
- ./SOM++ -cfg -cp ../Smalltalk ../TestSuite/TestHarness.som
8181
- ./unittests -cfg -cp ../Smalltalk:../TestSuite/BasicInterpreterTests ../Examples/Hello.som
82+
- ./SOM++ -prim-hash-check -cp ../Smalltalk ../Examples/Benchmarks/BenchmarkHarness.som VectorBenchmark 1 1
8283
- cd ..
8384

8485
- cd release

src/primitivesCore/PrimitiveContainer.cpp

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@
3333
#include <string>
3434
#include <utility>
3535

36+
#include "../vm/Print.h"
3637
#include "../vm/Symbols.h"
38+
#include "../vm/Universe.h"
3739
#include "../vmobjects/VMClass.h"
3840
#include "../vmobjects/VMInvokable.h"
3941
#include "../vmobjects/VMPrimitive.h"
4042
#include "../vmobjects/VMSafePrimitive.h"
4143
#include "../vmobjects/VMSymbol.h"
44+
#include "/Users/smarr/Projects/SOM/SOMpp/src/vm/Print.h"
4245
#include "Primitives.h"
4346

4447
void PrimitiveContainer::Add(const char* name,
@@ -133,10 +136,12 @@ void PrimitiveContainer::Add(const char* name, bool classSide,
133136
}
134137

135138
template <class PrimT>
136-
void PrimitiveContainer::installPrimitives(
139+
bool PrimitiveContainer::installPrimitives(
137140
bool classSide, bool showWarning, VMClass* clazz,
138141
std::map<std::string, std::pair<PrimT, PrimT>>& prims,
139142
VMInvokable* (*makePrimFn)(VMSymbol* sig, PrimT)) {
143+
bool hasHashMismatch = false;
144+
140145
for (auto const& p : prims) {
141146
PrimT prim1 = std::get<0>(p.second);
142147
PrimT prim2 = std::get<1>(p.second);
@@ -150,27 +155,55 @@ void PrimitiveContainer::installPrimitives(
150155

151156
PrimInstallResult const result = clazz->InstallPrimitive(
152157
makePrimFn(sig, prim1), prim1.bytecodeHash, !prim2.IsValid());
158+
if (!prim2.IsValid()) {
159+
hasHashMismatch =
160+
hasHashMismatch || result == PrimInstallResult::HASH_MISMATCH;
161+
}
162+
153163
if (result == PrimInstallResult::INSTALLED_ADDED && showWarning) {
154164
cout << "Warn: Primitive " << p.first
155165
<< " is not in class definition for class "
156166
<< clazz->GetName()->GetStdString() << '\n';
157167
} else if (result == PrimInstallResult::HASH_MISMATCH &&
158168
prim2.IsValid()) {
159169
assert(prim1.isClassSide == prim2.isClassSide);
160-
clazz->InstallPrimitive(makePrimFn(sig, prim2), prim2.bytecodeHash,
161-
true);
170+
PrimInstallResult const result2 = clazz->InstallPrimitive(
171+
makePrimFn(sig, prim2), prim2.bytecodeHash, true);
172+
hasHashMismatch =
173+
hasHashMismatch || result2 == PrimInstallResult::HASH_MISMATCH;
162174
}
163175
}
176+
177+
return hasHashMismatch;
164178
}
165179

166180
void PrimitiveContainer::InstallPrimitives(VMClass* clazz, bool classSide,
167181
bool showWarning) {
168-
installPrimitives(classSide, showWarning, clazz, unaryPrims,
169-
VMSafePrimitive::GetSafeUnary);
170-
installPrimitives(classSide, showWarning, clazz, binaryPrims,
171-
VMSafePrimitive::GetSafeBinary);
172-
installPrimitives(classSide, showWarning, clazz, ternaryPrims,
173-
VMSafePrimitive::GetSafeTernary);
174-
installPrimitives(classSide, showWarning, clazz, framePrims,
175-
VMPrimitive::GetFramePrim);
182+
bool hasHashMismatch = false;
183+
hasHashMismatch =
184+
hasHashMismatch ||
185+
installPrimitives(classSide, showWarning, clazz, unaryPrims,
186+
VMSafePrimitive::GetSafeUnary);
187+
hasHashMismatch =
188+
hasHashMismatch ||
189+
installPrimitives(classSide, showWarning, clazz, binaryPrims,
190+
VMSafePrimitive::GetSafeBinary);
191+
hasHashMismatch =
192+
hasHashMismatch ||
193+
installPrimitives(classSide, showWarning, clazz, ternaryPrims,
194+
VMSafePrimitive::GetSafeTernary);
195+
hasHashMismatch = hasHashMismatch ||
196+
installPrimitives(classSide, showWarning, clazz,
197+
framePrims, VMPrimitive::GetFramePrim);
198+
199+
if (abortOnCoreLibHashMismatch && hasHashMismatch) {
200+
ErrorPrint("The implementation of methods in " +
201+
clazz->GetName()->GetStdString() +
202+
" seem to have changed.\n");
203+
ErrorPrint(
204+
"The primitive implementation in the matching VM class may need to "
205+
"be changed. See for instance _Vector::_Vector() in "
206+
"primitives/Vector.cpp\n");
207+
Quit(1);
208+
}
176209
}

src/primitivesCore/PrimitiveContainer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class PrimitiveContainer {
8181
std::map<std::string, std::pair<TernaryPrim, TernaryPrim>> ternaryPrims;
8282

8383
template <class PrimT>
84-
void installPrimitives(
84+
bool installPrimitives(
8585
bool classSide, bool showWarning, VMClass* clazz,
8686
std::map<std::string, std::pair<PrimT, PrimT>>& prims,
8787
VMInvokable* (*makePrimFn)(VMSymbol* sig, PrimT));

src/vm/Universe.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static gc_oop_t prebuildInts[INT_CACHE_MAX_VALUE - INT_CACHE_MIN_VALUE + 1];
7474

7575
uint8_t dumpBytecodes;
7676
uint8_t gcVerbosity;
77-
bool printCoreLibMethodHashes = false;
77+
bool abortOnCoreLibHashMismatch = false;
7878

7979
static std::string bm_name;
8080

@@ -212,8 +212,8 @@ vector<std::string> Universe::handleArguments(int32_t argc, char** argv) {
212212
} else if ((strncmp(argv[i], "-h", 2) == 0) ||
213213
(strncmp(argv[i], "--help", 6) == 0)) {
214214
printUsageAndExit(argv[0]);
215-
} else if ((strncmp(argv[i], "-prim-hashes", 12)) == 0) {
216-
printCoreLibMethodHashes = true;
215+
} else if ((strncmp(argv[i], "-prim-hash-check", 16)) == 0) {
216+
abortOnCoreLibHashMismatch = true;
217217
} else {
218218
vector<std::string> extPathTokens = vector<std::string>(2);
219219
std::string const tmpString = std::string(argv[i]);
@@ -283,10 +283,10 @@ void Universe::printUsageAndExit(char* executable) {
283283
cout << " set search path for application classes\n";
284284
cout << " -d enable disassembling (twice for tracing)\n";
285285
cout << " -cfg print VM configuration\n";
286-
cout << " -prim-hashes print hashes of core-lib methods\n";
287-
cout << " that have primitive replacements and exit with "
288-
"error\n";
289-
cout << " when they do not match expected results\n";
286+
cout << " -prim-hash-check check that method replacements have expected "
287+
"hash.\n";
288+
cout
289+
<< " Exit with error when a hash does not match.\n";
290290
cout
291291
<< " -g enable garbage collection details:\n"
292292
<< " 1x - print statistics when VM shuts down\n"

src/vm/Universe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class SourcecodeCompiler;
4141
// for runtime debug
4242
extern uint8_t dumpBytecodes;
4343
extern uint8_t gcVerbosity;
44-
extern bool printCoreLibMethodHashes;
44+
extern bool abortOnCoreLibHashMismatch;
4545

4646
using namespace std;
4747
class Universe {

src/vmobjects/VMClass.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include "../vm/Globals.h"
3939
#include "../vm/IsValidObject.h"
4040
#include "../vm/Print.h"
41-
#include "../vm/Universe.h"
4241
#include "ObjectFormats.h"
4342
#include "VMArray.h"
4443
#include "VMInvokable.h"
@@ -109,11 +108,6 @@ PrimInstallResult VMClass::InstallPrimitive(VMInvokable* invokable,
109108
hashMismatch = true;
110109
} else {
111110
seenHash = method->GetBytecodeHash();
112-
if (printCoreLibMethodHashes) {
113-
cout << "Method: "
114-
<< method->GetSignature()->AsDebugString()
115-
<< " has hash: " << seenHash << '\n';
116-
}
117111
if (seenHash == bytecodeHash) {
118112
result = PrimInstallResult::INSTALLED_REPLACED;
119113
} else {

0 commit comments

Comments
 (0)