Пример #1
0
  void GarbageCollector::clean_weakrefs(bool check_forwards) {
    if(!weak_refs_) return;

    for(ObjectArray::iterator i = weak_refs_->begin();
        i != weak_refs_->end();
        i++) {
      WeakRef* ref = try_as<WeakRef>(*i);
      if(!ref) continue; // WTF.

      Object* obj = ref->object();
      if(!obj->reference_p()) continue;

      if(check_forwards) {
        if(obj->young_object_p()) {
          if(!obj->forwarded_p()) {
            ref->set_object(object_memory_, Qnil);
          } else {
            ref->set_object(object_memory_, obj->forward());
          }
        }
      } else if(!obj->marked_p(object_memory_->mark())) {
        ref->set_object(object_memory_, Qnil);
      }
    }

    delete weak_refs_;
    weak_refs_ = NULL;
  }
Пример #2
0
SEXP R_WeakRefKey(SEXP w)
{
    if (w->sexptype() != WEAKREFSXP)
	Rf_error(_("not a weak reference"));
    WeakRef* wr = static_cast<WeakRef*>(w);
    return wr->key();
}
Пример #3
0
  void GarbageCollector::clean_weakrefs(bool check_forwards) {
    if(!weak_refs_) return;

    for(ObjectArray::iterator i = weak_refs_->begin();
        i != weak_refs_->end();
        ++i) {
      if(!*i) continue; // Object was removed during young gc.
      WeakRef* ref = try_as<WeakRef>(*i);
      if(!ref) continue; // Other type for some reason?

      Object* obj = ref->object();
      if(!obj->reference_p()) continue;

      if(check_forwards) {
        if(obj->young_object_p()) {
          if(!obj->forwarded_p()) {
            ref->set_object(object_memory_, cNil);
          } else {
            ref->set_object(object_memory_, obj->forward());
          }
        }
      } else if(!obj->marked_p(object_memory_->mark())) {
        ref->set_object(object_memory_, cNil);
      }
    }

    delete weak_refs_;
    weak_refs_ = NULL;
  }
Пример #4
0
bool WeakRef::runFinalizers()
{
    WeakRef::check();
    bool finalizer_run = !s_f10n_pending->empty();
    WRList::iterator lit = s_f10n_pending->begin();
    while (lit != s_f10n_pending->end()) {
	WeakRef* wr = *lit++;
	GCStackRoot<> topExp(R_CurrentExpr);
	size_t savestack = ProtectStack::size();
	{
	    // An Evaluator is declared for the finalizer to
	    // insure that any errors that might occur do not spill into
	    // the call that triggered the collection:
	    Evaluator evalr;
	    try {
		wr->finalize();
	    }
	    catch (CommandTerminated) {
	    }
	    // Expose WeakRef to reference-counting collection:
	    wr->m_self = 0;
	}
	ProtectStack::restoreSize(savestack);
	R_CurrentExpr = topExp;
    }
    return finalizer_run;
}
Пример #5
0
SEXP R_WeakRefValue(SEXP w)
{
    if (w->sexptype() != WEAKREFSXP)
	Rf_error(_("not a weak reference"));
    WeakRef* wr = static_cast<WeakRef*>(w);
    SEXP v = wr->value();
    if (v && NAMED(v) != 2)
	SET_NAMED(v, 2);
    return v;
}
Пример #6
0
void WeakRef::runExitFinalizers()
{
    WeakRef::check();
    WRList::iterator lit = s_live->begin();
    while (lit != s_live->end()) {
	WeakRef* wr = *lit++;
	if (wr->m_finalize_on_exit) {
	    wr->m_ready_to_finalize = true;
	    wr->transfer(s_live, s_f10n_pending);
	}
    }
    runFinalizers();
}
Пример #7
0
void WeakRef::markThru()
{
    WeakRef::check();
    WRList newlive;
    // Step 2-3 of algorithm.  Mark the value and R finalizer if the
    // key is marked.
    {
	unsigned int marks_applied;
	do {
	    GCNode::Marker marker;
	    WRList::iterator lit = s_live->begin();
	    while (lit != s_live->end()) {
		WeakRef* wr = *lit++;
		RObject* key = wr->key();
		if (key->isMarked()) {
		    RObject* value = wr->value();
		    if (value)
			marker(value);
		    FunctionBase* Rfinalizer = wr->m_Rfinalizer;
		    if (Rfinalizer)
			marker(Rfinalizer);
		    wr->transfer(s_live, &newlive);
		}
	    }
	    marks_applied = marker.marksApplied();
	} while (marks_applied > 0);
    }
    // Step 4 of algorithm.  Process references with unmarked keys.
    {
	GCNode::Marker marker;
	WRList::iterator lit = s_live->begin();
	while (lit != s_live->end()) {
	    WeakRef* wr = *lit++;
	    FunctionBase* Rfinalizer = wr->m_Rfinalizer;
	    if (Rfinalizer)
		marker(Rfinalizer);
	    if (Rfinalizer || wr->m_Cfinalizer) {
		marker(wr);
		marker(wr->m_key);
		wr->m_ready_to_finalize = true;
		wr->transfer(s_live, s_f10n_pending);
	    }
	    else {
		wr->tombstone();
		// Expose to reference-counting collection:
		wr->m_self = 0;
	    }
	}
    }
    // Step 5 of algorithm.  Mark all live references with reachable keys.
    {
	GCNode::Marker marker;
	s_live->splice(s_live->end(), newlive);
	for (WRList::iterator lit = s_live->begin();
	     lit != s_live->end(); ++lit) {
	    WeakRef* wr = *lit;
	    marker(wr);
	}
    }
}
Пример #8
0
 Object* Module::reset_method_cache(STATE, Symbol* name) {
   if(Class* self = try_as<Class>(this)) {
     self->increment_serial();
   }
   if(!name->nil_p()) {
     if(MethodTableBucket* b = method_table_->find_entry(state, name)) {
       Executable* exec = b->method();
       if(!exec->nil_p()) {
         exec->clear_inliners(state);
       }
     }
   }
   if(!hierarchy_subclasses_->nil_p()) {
     for(native_int i = 0; i < hierarchy_subclasses_->size(); ++i) {
       WeakRef* ref = try_as<WeakRef>(hierarchy_subclasses_->get(state, i));
       if(ref && ref->alive_p()) {
         Module* mod = as<Module>(ref->object());
         mod->reset_method_cache(state, name);
       }
     }
   }
   return cNil;
 }
Пример #9
0
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		return;

	typedef Pair<PropertyInfo, Variant> PropertyDesc;
	List<PropertyDesc> properties;

	if (ScriptInstance *si = obj->get_script_instance()) {
		if (!si->get_script().is_null()) {

			typedef Map<const Script *, Set<StringName> > ScriptMemberMap;
			typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap;

			ScriptMemberMap members;
			members[si->get_script().ptr()] = Set<StringName>();
			si->get_script()->get_members(&(members[si->get_script().ptr()]));

			ScriptConstantsMap constants;
			constants[si->get_script().ptr()] = Map<StringName, Variant>();
			si->get_script()->get_constants(&(constants[si->get_script().ptr()]));

			Ref<Script> base = si->get_script()->get_base_script();
			while (base.is_valid()) {

				members[base.ptr()] = Set<StringName>();
				base->get_members(&(members[base.ptr()]));

				constants[base.ptr()] = Map<StringName, Variant>();
				base->get_constants(&(constants[base.ptr()]));

				base = base->get_base_script();
			}

			for (ScriptMemberMap::Element *sm = members.front(); sm; sm = sm->next()) {
				for (Set<StringName>::Element *E = sm->get().front(); E; E = E->next()) {
					Variant m;
					if (si->get(E->get(), m)) {
						String script_path = sm->key() == si->get_script().ptr() ? "" : sm->key()->get_path().get_file() + "/";
						PropertyInfo pi(m.get_type(), "Members/" + script_path + E->get());
						properties.push_back(PropertyDesc(pi, m));
					}
				}
			}

			for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) {
				for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) {
					String script_path = sc->key() == si->get_script().ptr() ? "" : sc->key()->get_path().get_file() + "/";
					if (E->value().get_type() == Variant::OBJECT) {
						Variant id = ((Object *)E->value())->get_instance_id();
						PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
						properties.push_back(PropertyDesc(pi, id));
					} else {
						PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key());
						properties.push_back(PropertyDesc(pi, E->value()));
					}
				}
			}
		}
	}
	if (Node *node = Object::cast_to<Node>(obj)) {
		PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
		properties.push_front(PropertyDesc(pi, node->get_path()));
	} else if (Resource *res = Object::cast_to<Resource>(obj)) {
		if (Script *s = Object::cast_to<Script>(res)) {
			Map<StringName, Variant> constants;
			s->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				if (E->value().get_type() == Variant::OBJECT) {
					Variant id = ((Object *)E->value())->get_instance_id();
					PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object");
					properties.push_front(PropertyDesc(pi, E->value()));
				} else {
					PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
					properties.push_front(PropertyDesc(pi, E->value()));
				}
			}
		}
	}

	List<PropertyInfo> pinfo;
	obj->get_property_list(&pinfo, true);
	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.type);

		//only send information that can be sent..
		int len = 0; //test how big is this to encode
		encode_variant(var, NULL, len);
		if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			prop.push_back(pi.hint);
			prop.push_back(pi.hint_string);
			prop.push_back(pi.usage);

			if (!res.is_null()) {
				var = res->get_path();
			}

			prop.push_back(var);
		}
		send_props.push_back(prop);
	}

	packet_peer_stream->put_var("message:inspect_object");
	packet_peer_stream->put_var(3);
	packet_peer_stream->put_var(p_id);
	packet_peer_stream->put_var(obj->get_class());
	packet_peer_stream->put_var(send_props);
}
Пример #10
0
  void
  GC::Heap::mark(void) {
#if defined(MINIZINC_GC_STATS)
    std::cerr << "================= mark =================: ";
    gc_stats.clear();
#endif

    for (KeepAlive* e = _roots; e != NULL; e = e->next()) {
      if ((*e)() && (*e)()->_gc_mark==0) {
        Expression::mark((*e)());
#if defined(MINIZINC_GC_STATS)
        gc_stats[(*e)()->_id].keepalive++;
#endif
      }
    }
#if defined(MINIZINC_GC_STATS)
    std::cerr << "+";
#endif
    
    Model* m = _rootset;
    if (m==NULL)
      return;
    do {
      for (unsigned int j=0; j<m->_items.size(); j++) {
        Item* i = m->_items[j];
        if (i->_gc_mark==0) {
          i->_gc_mark = 1;
          i->loc().mark();
          switch (i->iid()) {
          case Item::II_INC:
            i->cast<IncludeI>()->f().mark();
            break;
          case Item::II_VD:
            Expression::mark(i->cast<VarDeclI>()->e());
#if defined(MINIZINC_GC_STATS)
            gc_stats[i->cast<VarDeclI>()->e()->Expression::eid()].inmodel++;
#endif
            break;
          case Item::II_ASN:
            i->cast<AssignI>()->id().mark();
            Expression::mark(i->cast<AssignI>()->e());
            Expression::mark(i->cast<AssignI>()->decl());
            break;
          case Item::II_CON:
            Expression::mark(i->cast<ConstraintI>()->e());
#if defined(MINIZINC_GC_STATS)
            gc_stats[i->cast<ConstraintI>()->e()->Expression::eid()].inmodel++;
#endif
            break;
          case Item::II_SOL:
            {
              SolveI* si = i->cast<SolveI>();
              for (ExpressionSetIter it = si->ann().begin(); it != si->ann().end(); ++it) {
                Expression::mark(*it);
              }
            }
            Expression::mark(i->cast<SolveI>()->e());
            break;
          case Item::II_OUT:
            Expression::mark(i->cast<OutputI>()->e());
            break;
          case Item::II_FUN:
            {
              FunctionI* fi = i->cast<FunctionI>();
              fi->id().mark();
              Expression::mark(fi->ti());
              for (ExpressionSetIter it = fi->ann().begin(); it != fi->ann().end(); ++it) {
                Expression::mark(*it);
              }
              Expression::mark(fi->e());
              fi->params().mark();
              for (unsigned int k=0; k<fi->params().size(); k++) {
                Expression::mark(fi->params()[k]);
              }
            }
            break;      
          }
        }
      }
      m = m->_roots_next;
    } while (m != _rootset);
    
    for (unsigned int i=trail.size(); i--;) {
      Expression::mark(trail[i].v);
    }
    
    for (WeakRef* wr = _weakRefs; wr != NULL; wr = wr->next()) {
      if ((*wr)() && (*wr)()->_gc_mark==0) {
        wr->_e = NULL;
        wr->_valid = false;
      }
    }

#if defined(MINIZINC_GC_STATS)
    std::cerr << "+";
    std::cerr << "\n";
#endif
  }
Пример #11
0
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		return;

	typedef Pair<PropertyInfo, Variant> PropertyDesc;
	List<PropertyDesc> properties;

	if (ScriptInstance *si = obj->get_script_instance()) {
		if (!si->get_script().is_null()) {

			Set<StringName> members;
			si->get_script()->get_members(&members);
			for (Set<StringName>::Element *E = members.front(); E; E = E->next()) {

				Variant m;
				if (si->get(E->get(), m)) {
					PropertyInfo pi(m.get_type(), String("Members/") + E->get());
					properties.push_back(PropertyDesc(pi, m));
				}
			}

			Map<StringName, Variant> constants;
			si->get_script()->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key()));
				properties.push_back(PropertyDesc(pi, E->value()));
			}
		}
	}
	if (Node *node = Object::cast_to<Node>(obj)) {
		PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
		properties.push_front(PropertyDesc(pi, node->get_path()));
	} else if (Resource *res = Object::cast_to<Resource>(obj)) {
		if (Script *s = Object::cast_to<Script>(res)) {
			Map<StringName, Variant> constants;
			s->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
				properties.push_front(PropertyDesc(pi, E->value()));
			}
		}
	}

	List<PropertyInfo> pinfo;
	obj->get_property_list(&pinfo, true);
	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.type);

		//only send information that can be sent..
		int len = 0; //test how big is this to encode
		encode_variant(var, NULL, len);
		if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			prop.push_back(pi.hint);
			if (res.is_null())
				prop.push_back(pi.hint_string);
			else
				prop.push_back(String("RES:") + res->get_path());
			prop.push_back(pi.usage);
			prop.push_back(var);
		}
		send_props.push_back(prop);
	}

	packet_peer_stream->put_var("message:inspect_object");
	packet_peer_stream->put_var(3);
	packet_peer_stream->put_var(p_id);
	packet_peer_stream->put_var(obj->get_class());
	packet_peer_stream->put_var(send_props);
}
Пример #12
0
 void WeakRef::Info::mark(Object* obj, ObjectMark& mark) {
   WeakRef* ref = as<WeakRef>(obj);
   if(ref->alive_p()) {
     mark.gc->add_weak_ref(obj);
   }
 }
Пример #13
0
  WeakRef* WeakRef::create(STATE, Object* obj) {
    WeakRef* ref = state->new_object<WeakRef>(G(cls_weakref));
    ref->set_object(state, obj);

    return ref;
  }
Пример #14
0
 void ReflectedProperty::ToString( const void * object, AString & buffer ) const
 {
     switch ( m_Type )
     {
         case PT_FLOAT:
         {
             float f;
             GetProperty( object, &f );
             buffer.Format( "%1.1f", f ); // TODO: Find a good format specifier
             return;
         }
         case PT_UINT8:
         {
             uint8_t u;
             GetProperty( object, &u );
             buffer.Format( "%u", u );
             return;
         }
         case PT_UINT16:
         {
             uint16_t u;
             GetProperty( object, &u );
             buffer.Format( "%u", u );
             return;
         }
         case PT_UINT32:
         {
             uint32_t u;
             GetProperty( object, &u );
             buffer.Format( "%u", u );
             return;
         }
         case PT_UINT64:
         {
             uint64_t u;
             GetProperty( object, &u );
             buffer.Format( "%" PRIu64, u );
             return;
         }
         case PT_INT8:
         {
             int8_t i;
             GetProperty( object, &i );
             buffer.Format( "%i", i );
             return;
         }
         case PT_INT16:
         {
             int16_t i;
             GetProperty( object, &i );
             buffer.Format( "%i", i );
             return;
         }
         case PT_INT32:
         {
             int32_t i;
             GetProperty( object, &i );
             buffer.Format( "%i", i );
             return;
         }
         case PT_INT64:
         {
             int64_t i;
             GetProperty( object, &i );
             buffer.Format( "%" PRIi64, i );
             return;
         }
         case PT_BOOL:
         {
             bool b;
             GetProperty( object, &b );
             buffer.Format( "%s", b ? "true" : "false" );
             return;
         }
         case PT_ASTRING:
         {
             AStackString<> str;
             GetProperty( object, &str );
             buffer.Format( "%s", str.Get() ); // TODO: Think about escaping
             break;
         }
         case PT_VEC2:
         {
             Vec2 v;
             GetProperty( object, &v );
             buffer.Format( "%.1f, %.1f", v.x, v.y ); // TODO: Find a good format specifier
             return;
         }
         case PT_VEC3:
         {
             Vec3 v;
             GetProperty( object, &v );
             buffer.Format( "%.1f, %.1f, %.1f", v.x, v.y, v.z ); // TODO: Find a good format specifier
             return;
         }
         case PT_VEC4:
         {
             Vec4 v;
             GetProperty( object, &v );
             buffer.Format( "%.1f, %.1f, %.1f, %.1f", v.x, v.y, v.z, v.w ); // TODO: Find a good format specifier
             return;
         }
         case PT_MAT44:
         {
             Mat44 m;
             GetProperty( object, &m );
             buffer.Format( "%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f", // TODO: Find a good format specifier
                     m.col0.x, m.col0.y, m.col0.z, m.col0.z,
                     m.col1.x, m.col1.y, m.col1.z, m.col1.z,
                     m.col2.x, m.col2.y, m.col2.z, m.col2.z,
                     m.col3.x, m.col3.y, m.col3.z, m.col3.z );
             return;
         }
         case PT_WEAKREF:
         {
             WeakRef< Object > w;
             GetProperty( object, &w );
             if ( w.Get() == nullptr )
             {
                 buffer.Format( "null" );
             }
             else
             {
                 w->GetScopedName( buffer );
             }
             return;
         }
         case PT_REF:
         case PT_STRUCT:
         {
             ASSERT( false ); // Unsupported
         }
         case PT_NONE:
         {
             ASSERT( false ); // Should be impossible
         }
     }
 }