From 1318bda1b24914bd49c4a82d3d89375e492342fd Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Fri, 4 May 2012 15:12:37 +0200 Subject: [PATCH] Remove boehm GC --- main.cpp | 2 -- qmljs_objects.cpp | 24 +++++++++---- qmljs_objects.h | 105 +++++++++++++++++++++++++++--------------------------- qmljs_runtime.cpp | 14 +++++--- qv4isel.cpp | 26 ++++++++------ v4.pro | 2 -- 6 files changed, 95 insertions(+), 78 deletions(-) diff --git a/main.cpp b/main.cpp index e5064b0..f16eec2 100644 --- a/main.cpp +++ b/main.cpp @@ -14,8 +14,6 @@ int main(int argc, char *argv[]) { using namespace QQmlJS; - GC_INIT(); - QCoreApplication app(argc, argv); QStringList args = app.arguments(); args.removeFirst(); diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index 580d6e5..e15c000 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -2,6 +2,11 @@ #include "qmljs_objects.h" #include +Object::~Object() +{ + delete members; +} + bool Object::get(String *name, Value *result) { if (Property *prop = getProperty(name)) { @@ -34,19 +39,22 @@ Property *Object::getProperty(String *name) void Object::put(String *name, const Value &value, bool flag) { + Q_UNUSED(flag); + if (! members) - members = new (GC) Table(); + members = new Table(); members->insert(name, value); } bool Object::canPut(String *name) { - if (Property *prop = getOwnProperty(name)) + if (Property *prop = getOwnProperty(name)) { + Q_UNUSED(prop); return true; - if (! prototype) + } else if (! prototype) { return extensible; - if (Property *inherited = prototype->getProperty(name)) { + } else if (Property *inherited = prototype->getProperty(name)) { return inherited->isWritable(); } else { return extensible; @@ -64,6 +72,8 @@ bool Object::hasProperty(String *name) const bool Object::deleteProperty(String *name, bool flag) { + Q_UNUSED(flag); + if (members) return members->remove(name); @@ -93,7 +103,9 @@ bool FunctionObject::hasInstance(const Value &value) const Value FunctionObject::call(const Value &thisObject, const Value args[], unsigned argc) { - (void) thisObject; + Q_UNUSED(thisObject); + Q_UNUSED(args); + Q_UNUSED(argc); Value v; __qmljs_init_undefined(0, &v); @@ -103,7 +115,7 @@ Value FunctionObject::call(const Value &thisObject, const Value args[], unsigned Value FunctionObject::construct(const Value args[], unsigned argc) { Value thisObject; - __qmljs_init_object(0, &thisObject, new (GC) Object); + __qmljs_init_object(0, &thisObject, new Object); call(thisObject, args, argc); return thisObject; } diff --git a/qmljs_objects.h b/qmljs_objects.h index 972ef4a..1945048 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -3,9 +3,9 @@ #include "qmljs_runtime.h" -#include #include #include +#include struct Value; struct Object; @@ -16,7 +16,7 @@ struct ArrayObject; struct FunctionObject; struct ErrorObject; -struct String: gc_cleanup { +struct String { String(const QString &text) : _text(text), _hashValue(0) {} @@ -32,7 +32,8 @@ struct String: gc_cleanup { } static String *get(Context *ctx, const QString &s) { - return new (GC) String(s); + Q_UNUSED(ctx); + return new String(s); } private: @@ -40,22 +41,26 @@ private: mutable unsigned _hashValue; }; -struct Property: gc { +struct Property { String *name; Value value; PropertyAttributes flags; Property *next; + int index; Property(String *name, const Value &value, PropertyAttributes flags = NoAttributes) - : name(name), value(value), flags(flags), next(0) {} + : name(name), value(value), flags(flags), next(0), index(-1) {} inline bool isWritable() const { return flags & WritableAttribute; } inline bool isEnumerable() const { return flags & EnumerableAttribute; } inline bool isConfigurable() const { return flags & ConfigurableAttribute; } inline bool hasName(String *n) const { - if (name == n || (name->hashValue() == n->hashValue() && name->text() == n->text())) + if (name == n) { return true; + } else if (name->hashValue() == n->hashValue() && name->text() == n->text()) { + return true; + } return false; } @@ -64,13 +69,9 @@ struct Property: gc { } }; -class Table: public gc +class Table { - Property **_properties; - Property **_buckets; - int _propertyCount; - int _bucketCount; - int _allocated; + Q_DISABLE_COPY(Table) public: Table() @@ -80,47 +81,33 @@ public: , _bucketCount(11) , _allocated(0) {} - bool empty() const { return _propertyCount == -1; } - unsigned size() const { return _propertyCount + 1; } + ~Table() + { + qDeleteAll(_properties, _properties + _propertyCount + 1); + delete[] _properties; + delete[] _buckets; + } + + inline bool isEmpty() const { return _propertyCount == -1; } typedef Property **iterator; - iterator begin() const { return _properties; } - iterator end() const { return _properties + (_propertyCount + 1); } + inline iterator begin() const { return _properties; } + inline iterator end() const { return _properties + (_propertyCount + 1); } bool remove(String *name) { - if (_properties) { - const unsigned hash = name->hashValue() % _bucketCount; - - if (Property *prop = _buckets[hash]) { - if (prop->hasName(name)) { - _buckets[hash] = prop->next; - return true; - } - - do { - Property *next = prop->next; - - if (next && next->hasName(name)) { - prop->next = next->next; - return true; - } - prop = next; - } while (prop); - } - } - + Q_UNUSED(name); + assert(!"TODO"); return false; } Property *find(String *name) const { - if (! _properties) - return 0; - - for (Property *prop = _buckets[name->hashValue() % _bucketCount]; prop; prop = prop->next) { - if (prop->hasName(name)) - return prop; + if (_properties) { + for (Property *prop = _buckets[name->hashValue() % _bucketCount]; prop; prop = prop->next) { + if (prop->hasName(name)) + return prop; + } } return 0; @@ -139,12 +126,14 @@ public: else _allocated *= 2; - Property **properties = new (GC) Property*[_allocated]; + Property **properties = new Property*[_allocated]; std::copy(_properties, _properties + _propertyCount, properties); + delete[] _properties; _properties = properties; } - Property *prop = new (GC) Property(name, value); + Property *prop = new Property(name, value); + prop->index = _propertyCount; _properties[_propertyCount] = prop; if (! _buckets || 3 * _propertyCount >= 2 * _bucketCount) { @@ -164,19 +153,29 @@ private: if (_bucketCount) _bucketCount *= 2; // ### next prime - _buckets = new (GC) Property *[_bucketCount]; + if (_buckets) + delete[] _buckets; + + _buckets = new Property *[_bucketCount]; std::fill(_buckets, _buckets + _bucketCount, (Property *) 0); for (int i = 0; i <= _propertyCount; ++i) { Property *prop = _properties[i]; - Property *&bucket = _buckets[prop->name->hashValue() % _bucketCount]; + Property *&bucket = _buckets[prop->hashValue() % _bucketCount]; prop->next = bucket; bucket = prop; } } + +private: + Property **_properties; + Property **_buckets; + int _propertyCount; + int _bucketCount; + int _allocated; }; -struct Object: gc_cleanup { +struct Object { Object *prototype; String *klass; Table *members; @@ -188,7 +187,7 @@ struct Object: gc_cleanup { , members(0) , extensible(true) {} - virtual ~Object() {} + virtual ~Object(); virtual FunctionObject *asFunctionObject() { return 0; } @@ -206,19 +205,19 @@ struct Object: gc_cleanup { struct BooleanObject: Object { Value value; BooleanObject(const Value &value): value(value) {} - virtual void defaultValue(Value *result, int typehint) { *result = value; } + virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; } }; struct NumberObject: Object { Value value; NumberObject(const Value &value): value(value) {} - virtual void defaultValue(Value *result, int typehint) { *result = value; } + virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; } }; struct StringObject: Object { Value value; StringObject(const Value &value): value(value) {} - virtual void defaultValue(Value *result, int typehint) { *result = value; } + virtual void defaultValue(Value *result, int /*typehint*/) { *result = value; } }; struct ArrayObject: Object { @@ -244,7 +243,7 @@ struct ErrorObject: Object { struct ArgumentsObject: Object { }; -struct Context: gc { +struct Context { Value activation; Value thisObject; Object *scope; diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp index cc811c7..3e4f6a5 100644 --- a/qmljs_runtime.cpp +++ b/qmljs_runtime.cpp @@ -58,9 +58,11 @@ void __qmljs_string_literal_function(Context *ctx, Value *result) void __qmljs_delete(Context *ctx, Value *result, const Value *value) { + Q_UNIMPLEMENTED(); (void) ctx; (void) result; (void) value; + assert(!"TODO"); } void __qmljs_instanceof(Context *ctx, Value *result, const Value *left, const Value *right) @@ -129,37 +131,39 @@ bool __qmljs_is_function(Context *, const Value *value) void __qmljs_object_default_value(Context *ctx, Value *result, Object *object, int typeHint) { + Q_UNUSED(ctx); object->defaultValue(result, typeHint); } void __qmljs_throw_type_error(Context *ctx, Value *result) { - __qmljs_init_object(ctx, result, new (GC) ErrorObject(String::get(ctx, QLatin1String("type error")))); + __qmljs_init_object(ctx, result, new ErrorObject(String::get(ctx, QLatin1String("type error")))); } void __qmljs_new_boolean_object(Context *ctx, Value *result, bool boolean) { Value value; __qmljs_init_boolean(ctx, &value, boolean); - __qmljs_init_object(ctx, result, new (GC) BooleanObject(value)); + __qmljs_init_object(ctx, result, new BooleanObject(value)); } void __qmljs_new_number_object(Context *ctx, Value *result, double number) { Value value; __qmljs_init_number(ctx, &value, number); - __qmljs_init_object(ctx, result, new (GC) NumberObject(value)); + __qmljs_init_object(ctx, result, new NumberObject(value)); } void __qmljs_new_string_object(Context *ctx, Value *result, String *string) { Value value; __qmljs_init_string(ctx, &value, string); - __qmljs_init_object(ctx, result, new (GC) StringObject(value)); + __qmljs_init_object(ctx, result, new StringObject(value)); } void __qmljs_set_property(Context *ctx, Value *object, String *name, Value *value) { + Q_UNUSED(ctx); object->objectValue->put(name, *value, /*flags*/ 0); } @@ -211,6 +215,7 @@ void __qmljs_set_activation_property_string(Context *ctx, String *name, String * void __qmljs_get_property(Context *ctx, Value *result, Value *object, String *name) { + Q_UNUSED(ctx); Q_ASSERT(object->type == OBJECT_TYPE); object->objectValue->get(name, result); } @@ -232,6 +237,7 @@ void __qmljs_get_thisObject(Context *ctx, Value *result) void __qmljs_copy_property(Context *ctx, Value *target, String *name, Value *source, String *other) { + Q_UNUSED(ctx); Value v; source->objectValue->get(other, &v); target->objectValue->put(name, v); diff --git a/qv4isel.cpp b/qv4isel.cpp index f3c4c66..94f3d2c 100644 --- a/qv4isel.cpp +++ b/qv4isel.cpp @@ -164,8 +164,8 @@ void InstructionSelection::visitFunction(IR::Function *function) void (*f)(Context *) = (void (*)(Context *)) code; - Context *ctx = new (GC) Context; - ctx->activation = Value::object(ctx, new (GC) ArgumentsObject); + Context *ctx = new Context; + ctx->activation = Value::object(ctx, new ArgumentsObject); f(ctx); Value d; ctx->activation.objectValue->get(identifier("d"), &d); @@ -177,7 +177,7 @@ String *InstructionSelection::identifier(const QString &s) { String *&id = _identifiers[s]; if (! id) - id = new (GC) String(s); + id = new String(s); return id; } @@ -191,21 +191,21 @@ void InstructionSelection::loadTempAddress(int reg, IR::Temp *t) amd64_lea_membase(_codePtr, reg, AMD64_RSP, sizeof(Value) * (t->index - 1)); } -void InstructionSelection::visitExp(IR::Exp *s) +void InstructionSelection::visitExp(IR::Exp *) { - // if (IR::Call *c = s->expr->asCall()) { - // return; - // } + Q_UNIMPLEMENTED(); assert(!"TODO"); } void InstructionSelection::visitEnter(IR::Enter *) { + Q_UNIMPLEMENTED(); assert(!"TODO"); } void InstructionSelection::visitLeave(IR::Leave *) { + Q_UNIMPLEMENTED(); assert(!"TODO"); } @@ -233,13 +233,14 @@ void InstructionSelection::visitMove(IR::Move *s) break; default: + Q_UNIMPLEMENTED(); assert(!"TODO"); } return; } else if (IR::String *str = s->source->asString()) { amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8); amd64_mov_reg_imm(_codePtr, AMD64_RSI, propertyName); - amd64_mov_reg_imm(_codePtr, AMD64_RDX, new (GC) String(*str->value)); + amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value)); amd64_call_code(_codePtr, __qmljs_set_activation_property_string); return; } else if (IR::Temp *t = s->source->asTemp()) { @@ -280,13 +281,14 @@ void InstructionSelection::visitMove(IR::Move *s) break; default: + Q_UNIMPLEMENTED(); assert(!"TODO"); } return; } else if (IR::String *str = s->source->asString()) { amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8); loadTempAddress(AMD64_RSI, t); - amd64_mov_reg_imm(_codePtr, AMD64_RDX, new (GC) String(*str->value)); + amd64_mov_reg_imm(_codePtr, AMD64_RDX, new String(*str->value)); amd64_call_code(_codePtr, __qmljs_init_string); return; } else if (IR::Unop *u = s->source->asUnop()) { @@ -361,6 +363,7 @@ void InstructionSelection::visitMove(IR::Move *s) } else { // inplace assignment, e.g. x += 1, ++x, ... } + Q_UNIMPLEMENTED(); assert(!"TODO"); } @@ -388,12 +391,13 @@ void InstructionSelection::visitCJump(IR::CJump *s) } return; } + Q_UNIMPLEMENTED(); assert(!"TODO"); } void InstructionSelection::visitRet(IR::Ret *s) { - qWarning() << "TODO: RET"; - //assert(!"TODO"); + Q_UNIMPLEMENTED(); + Q_UNUSED(s); } diff --git a/v4.pro b/v4.pro index 5857112..b50ea3e 100644 --- a/v4.pro +++ b/v4.pro @@ -4,8 +4,6 @@ CONFIG += console DEFINES += __default_codegen__ -LIBS += -lgc - udis86:LIBS += -ludis86 else:DEFINES += NO_UDIS86 -- 2.7.4