// The cache_entries parameter is empty (on cold call site) or has entries // (on cache miss). Called from assembly with the actual return address. // Compilation of the inline cache may trigger a GC, which may trigger a // compaction; // also, the block containing the return address may now be dead. Use a // code_root to take care of the details. // Allocates memory cell factor_vm::inline_cache_miss(cell return_address_) { code_root return_address(return_address_, this); bool tail_call_site = tail_call_site_p(return_address.value); #ifdef PIC_DEBUG FACTOR_PRINT("Inline cache miss at " << (tail_call_site ? "tail" : "non-tail") << " call site 0x" << std::hex << return_address.value << std::dec); print_callstack(); #endif data_root<array> cache_entries(ctx->pop(), this); fixnum index = untag_fixnum(ctx->pop()); data_root<array> methods(ctx->pop(), this); data_root<word> generic_word(ctx->pop(), this); data_root<object> object(((cell*)ctx->datastack)[-index], this); cell pic_size = array_capacity(cache_entries.untagged()) / 2; update_pic_transitions(pic_size); cell xt = generic_word->entry_point; if (pic_size < max_pic_size) { cell klass = object_class(object.value()); cell method = lookup_method(object.value(), methods.value()); data_root<array> new_cache_entries( add_inline_cache_entry(cache_entries.value(), klass, method), this); inline_cache_jit jit(generic_word.value(), this); jit.emit_inline_cache(index, generic_word.value(), methods.value(), new_cache_entries.value(), tail_call_site); code_block* code = jit.to_code_block(CODE_BLOCK_PIC, JIT_FRAME_SIZE); initialize_code_block(code); xt = code->entry_point(); } // Install the new stub. if (return_address.valid) { // Since each PIC is only referenced from a single call site, // if the old call target was a PIC, we can deallocate it immediately, // instead of leaving dead PICs around until the next GC. deallocate_inline_cache(return_address.value); set_call_target(return_address.value, xt); #ifdef PIC_DEBUG FACTOR_PRINT("Updated " << (tail_call_site ? "tail" : "non-tail") << " call site 0x" << std::hex << return_address.value << std::dec << " with 0x" << std::hex << (cell)xt << std::dec); print_callstack(); #endif } return xt; }
/* The cache_entries parameter is either f (on cold call site) or an array (on cache miss). Called from assembly with the actual return address */ void *factor_vm::inline_cache_miss(cell return_address) { check_code_pointer(return_address); /* Since each PIC is only referenced from a single call site, if the old call target was a PIC, we can deallocate it immediately, instead of leaving dead PICs around until the next GC. */ deallocate_inline_cache(return_address); gc_root<array> cache_entries(dpop(),this); fixnum index = untag_fixnum(dpop()); gc_root<array> methods(dpop(),this); gc_root<word> generic_word(dpop(),this); gc_root<object> object(((cell *)ds)[-index],this); void *xt; cell pic_size = inline_cache_size(cache_entries.value()); update_pic_transitions(pic_size); if(pic_size >= max_pic_size) xt = megamorphic_call_stub(generic_word.value()); else { cell klass = object_class(object.value()); cell method = lookup_method(object.value(),methods.value()); gc_root<array> new_cache_entries(add_inline_cache_entry( cache_entries.value(), klass, method),this); xt = compile_inline_cache(index, generic_word.value(), methods.value(), new_cache_entries.value(), tail_call_site_p(return_address))->xt(); } /* Install the new stub. */ set_call_target(return_address,xt); #ifdef PIC_DEBUG printf("Updated %s call site 0x%lx with 0x%lx\n", tail_call_site_p(return_address) ? "tail" : "non-tail", return_address, (cell)xt); #endif return xt; }
void * z_object_connect(Self *self,char *name,ZObject *target,char *method_name,void *userdata) { { #if !defined(BOOTSTRAP) ZClosure *closure; ZObjectSignalHandler handler; assert(selfp->signal_map != NULL); /* Increase the reference count of self so it stays alive for the disconnect() call. */ ref(self); /* lookup handler from method_name */ handler = lookup_method(target, method_name); assert(handler != NULL); /* create a closure */ closure = z_closure_new(CTX_FROM_OBJECT(self), ALLOCATOR_FROM_OBJECT(self)); z_closure_set_target(closure, target); z_closure_set_handler(closure, handler); z_closure_set_userdata(closure, userdata); /* locate signal's closure list by name */ ZMap *signal_map = (ZMap *) selfp->signal_map; ZMapIter *it = z_map_find(signal_map, name); assert(it != NULL); ZVector *closure_list = z_map_get_value(signal_map, it); unref(Z_OBJECT(it)); /* add new closure into the signal */ z_vector_push_back(closure_list, closure); return closure; #else return NULL; #endif } }
void factor_vm::primitive_lookup_method() { cell methods = dpop(); cell obj = dpop(); dpush(lookup_method(obj,methods)); }
//========================================================================= scx::Condition GetFileHandler::handle_message(MessageStream* message) { const Request& request = message->get_request(); Response& response = message->get_response(); if (request.get_method() != "GET" && request.get_method() != "HEAD" ) { // Don't understand the method response.set_status(http::Status::NotImplemented); return scx::Close; } // Open the file scx::FilePath path = request.get_path(); scx::File* file = new scx::File(); if (file->open(path,scx::File::Read) != scx::Ok) { message->log("Cannot open file '" + path.path() + "'"); response.set_status(http::Status::Forbidden); delete file; return scx::Close; } // Find last modified date scx::Date lastmod = file->stat().time(); response.set_header("Last-Modified",lastmod.string()); std::string mod = request.get_header("If-Modified-Since"); if (!mod.empty()) { scx::Date dmod = scx::Date(mod); if (lastmod <= dmod) { message->log("File is not modified"); response.set_status(http::Status::NotModified); delete file; return scx::Close; } } response.set_status(http::Status::Ok); // Set content length int clength = file->size(); std::ostringstream oss; oss << clength; response.set_header("Content-Length",oss.str()); // Lookup MIME type for file bool compressible = false; scx::Module::Ref mime = scx::Kernel::get()->get_module("mime"); if (mime.valid()) { scx::ScriptList::Ref args(new scx::ScriptList()); args.object()->give( scx::ScriptString::new_ref(path.path()) ); scx::ScriptMethodRef lookup_method(mime,"lookup"); scx::MimeType* mimetype = 0; scx::ScriptRef* ret = lookup_method.call(scx::ScriptAuth::Untrusted,&args); if (ret && (mimetype = dynamic_cast<scx::MimeType*>(ret->object()))) { response.set_header("Content-Type",mimetype->get_string()); } // Decide if the file is compressible, this will be used to // determine whether to use gzip to send it. compressible = (mimetype->get_type() == "text"); delete ret; } if (request.get_method() == "HEAD") { // Don't actually send the file, just the headers message->log("GetFile headers for '" + path.path() + "'"); delete file; return scx::Close; } message->log("GetFile '" + path.path() + "'"); // Decide whether to use gzip // This is based on whether the file is compressible (text) // and if it is over a certain size (i.e. worth compressing) if (compressible && clength > 1000) { // Also check if the client accepts gzip encoding bool gzip_accepted = false; scx::MimeHeader ae = request.get_header_parsed("Accept-Encoding"); for (int i=0; i<ae.num_values(); ++i) { if (ae.get_value(i)->value() == "gzip") { gzip_accepted = true; break; } } if (gzip_accepted) { message->log("Using gzip"); message->add_stream(new scx::GzipStream(0,16384)); response.set_header("Content-Encoding","gzip"); // Unfortunately we have to remove the content-length, so // chunked encoding will be used for gzipped content. response.remove_header("Content-Length"); } } const int MAX_BUFFER_SIZE = 65536; scx::StreamTransfer* xfer = new scx::StreamTransfer(file,std::min(clength,MAX_BUFFER_SIZE)); xfer->set_close_when_finished(true); message->add_stream(xfer); // Add file to kernel scx::Kernel::get()->connect(file); return scx::Ok; }
static bool init_ids(JNIEnv* env) { // Load NativeObject classes init_class(env, "mapnik/NativeObject", CLASS_NATIVEOBJECT); init_class(env, "mapnik/MapDefinition", CLASS_MAP); init_class(env, "mapnik/Datasource", CLASS_DATASOURCE); init_class(env, "mapnik/DatasourceCache", CLASS_DATASOURCE_CACHE); init_class(env, "mapnik/Layer", CLASS_LAYER); init_class(env, "mapnik/FeatureTypeStyle", CLASS_FEATURE_TYPE_STYLE); init_class(env, "mapnik/Projection", CLASS_PROJECTION); init_class(env, "mapnik/Query", CLASS_QUERY); init_class(env, "mapnik/FeatureSet", CLASS_FEATURESET); init_class(env, "mapnik/Geometry", CLASS_GEOMETRY); init_class(env, "mapnik/Image", CLASS_IMAGE); init_class(env, "mapnik/Grid", CLASS_GRID); // Ptr CTOR_NATIVEOBJECT=lookup_method(env, CLASS_NATIVEOBJECT, "<init>", "()V"); FIELD_PTR=lookup_field(env, CLASS_NATIVEOBJECT, "ptr", "J"); // FeatureSet FIELD_FEATURESET_FEATURE_PTR=lookup_field(env, CLASS_FEATURESET, "feature_ptr", "J"); // String init_class(env, "java/lang/String", CLASS_STRING); // Integer init_class(env, "java/lang/Integer", CLASS_INTEGER); METHOD_INTEGER_VALUEOF=lookup_static_method(env, CLASS_INTEGER, "valueOf", "(I)Ljava/lang/Integer;"); init_class(env, "java/lang/Boolean", CLASS_BOOLEAN); METHOD_BOOLEAN_VALUEOF=lookup_static_method(env, CLASS_BOOLEAN, "valueOf", "(Z)Ljava/lang/Boolean;"); init_class(env, "java/lang/Long", CLASS_LONG); METHOD_LONG_VALUEOF=lookup_static_method(env, CLASS_LONG, "valueOf", "(J)Ljava/lang/Long;"); // Double init_class(env, "java/lang/Double", CLASS_DOUBLE); METHOD_DOUBLE_VALUEOF=lookup_static_method(env, CLASS_DOUBLE, "valueOf", "(D)Ljava/lang/Double;"); // Parameters init_class(env, "mapnik/Parameters", CLASS_PARAMETERS); CTOR_PARAMETERS=lookup_method(env, CLASS_PARAMETERS, "<init>", "()V"); METHOD_PARAMETERS_SET_STRING=lookup_method(env, CLASS_PARAMETERS, "setString", "(Ljava/lang/String;Ljava/lang/String;)V"); METHOD_PARAMETERS_SET_BOOLEAN=lookup_method(env, CLASS_PARAMETERS, "setBool", "(Ljava/lang/String;Z)V"); METHOD_PARAMETERS_SET_INT=lookup_method(env, CLASS_PARAMETERS, "setInt", "(Ljava/lang/String;I)V"); METHOD_PARAMETERS_SET_LONG=lookup_method(env, CLASS_PARAMETERS, "setLong", "(Ljava/lang/String;J)V"); METHOD_PARAMETERS_SET_DOUBLE=lookup_method(env, CLASS_PARAMETERS, "setDouble", "(Ljava/lang/String;D)V"); METHOD_PARAMETERS_COPY_TO_NATIVE=lookup_method(env, CLASS_PARAMETERS, "copyToNative", "(J)V"); // HashSet init_class(env, "java/util/HashSet", CLASS_HASHSET); CTOR_HASHSET=lookup_method(env, CLASS_HASHSET, "<init>", "()V"); METHOD_HASHSET_ADD=lookup_method(env, CLASS_HASHSET, "add", "(Ljava/lang/Object;)Z"); // Box2d init_class(env, "mapnik/Box2d", CLASS_BOX2D); FIELD_BOX2D_MINX=lookup_field(env, CLASS_BOX2D, "minx", "D"); FIELD_BOX2D_MINY=lookup_field(env, CLASS_BOX2D, "miny", "D"); FIELD_BOX2D_MAXX=lookup_field(env, CLASS_BOX2D, "maxx", "D"); FIELD_BOX2D_MAXY=lookup_field(env, CLASS_BOX2D, "maxy", "D"); // Color init_class(env, "mapnik/Color", CLASS_COLOR); FIELD_COLOR_RED=lookup_field(env, CLASS_COLOR, "red", "I"); FIELD_COLOR_GREEN=lookup_field(env, CLASS_COLOR, "green", "I"); FIELD_COLOR_BLUE=lookup_field(env, CLASS_COLOR, "blue", "I"); FIELD_COLOR_ALPHA=lookup_field(env, CLASS_COLOR, "alpha", "I"); // Coord init_class(env, "mapnik/Coord", CLASS_COORD); FIELD_COORD_X=lookup_field(env, CLASS_COORD, "x", "D"); FIELD_COORD_Y=lookup_field(env, CLASS_COORD, "y", "D"); // LayerDescriptor init_class(env, "mapnik/LayerDescriptor", CLASS_LAYERDESCRIPTOR); CTOR_LAYERDESCRIPTOR=lookup_method(env, CLASS_LAYERDESCRIPTOR, "<init>", "()V"); FIELD_LAYERDESCRIPTOR_NAME=lookup_field(env, CLASS_LAYERDESCRIPTOR, "name", "Ljava/lang/String;"); FIELD_LAYERDESCRIPTOR_ENCODING=lookup_field(env, CLASS_LAYERDESCRIPTOR, "encoding", "Ljava/lang/String;"); METHOD_LAYERDESCRIPTOR_ADDDESCRIPTOR=lookup_method(env, CLASS_LAYERDESCRIPTOR, "addDescriptor", "(Lmapnik/AttributeDescriptor;)V"); // AttributeDescriptor init_class(env, "mapnik/AttributeDescriptor", CLASS_ATTRIBUTEDESCRIPTOR); CTOR_ATTRIBUTEDESCRIPTOR=lookup_method(env, CLASS_ATTRIBUTEDESCRIPTOR, "<init>", "()V"); FIELD_ATTRIBUTEDESCRIPTOR_NAME=lookup_field(env, CLASS_ATTRIBUTEDESCRIPTOR, "name", "Ljava/lang/String;"); FIELD_ATTRIBUTEDESCRIPTOR_TYPE=lookup_field(env, CLASS_ATTRIBUTEDESCRIPTOR, "type", "I"); FIELD_ATTRIBUTEDESCRIPTOR_PRIMARYKEY=lookup_field(env, CLASS_ATTRIBUTEDESCRIPTOR, "primaryKey", "Z"); FIELD_ATTRIBUTEDESCRIPTOR_SIZE=lookup_field(env, CLASS_ATTRIBUTEDESCRIPTOR, "size", "I"); FIELD_ATTRIBUTEDESCRIPTOR_PRECISION=lookup_field(env, CLASS_ATTRIBUTEDESCRIPTOR, "precision", "I"); return true; }