00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "slate.hpp"
00029 #include <signal.h>
00030
00031 word_t memory_string_to_bytes(char* str) {
00032
00033 word_t res = atoi(str);
00034
00035 if (strstr(str, "GB")) {
00036 return res * GB;
00037
00038 } else if (strstr(str, "MB")) {
00039 return res * MB;
00040
00041 } else if (strstr(str, "KB")) {
00042 return res * KB;
00043
00044 } else {
00045 return res;
00046 }
00047
00048 }
00049
00050 int globalInterrupt = 0;
00051
00052 void slate_interrupt_handler(int sig) {
00053 globalInterrupt = 1;
00054 }
00055
00056 void print_usage (char *progName) {
00057 fprintf(stderr, "Usage: %s [options]\n", progName);
00058 fprintf(stderr, " -h, --help Print this help message, then exit\n");
00059 fprintf(stderr, " -v, --version Print the VM version, then exit\n");
00060 fprintf(stderr, " -i, --image <image> Specify a non-default image file to start with\n");
00061 fprintf(stderr, " -mo <bytes>(GB|MB|KB) Old memory for tenured/old objects (Default 400MB)\n");
00062 fprintf(stderr, " -mn <bytes>(GB|MB|KB) New memory for young/new objects (Default 10MB)\n");
00063
00064 fprintf(stderr, " -q, --quiet Quiet mode (suppress many stdout messages)\n");
00065 fprintf(stderr, " -gc, --show-gc Show Garbage Collector messages\n");
00066 fprintf(stderr, " --image-help Print the help message for the image\n");
00067 fprintf(stderr, "\nNotes:\n");
00068 fprintf(stderr, "<image> defaults: `./%s', then `%s/%s'.\n", xstr (SLATE_DEFAULT_IMAGE), xstr (SLATE_DATADIR), xstr (SLATE_DEFAULT_IMAGE));
00069 }
00070
00071 int main(int argc, char** argv, char **envp) {
00072
00073 const char* image_name = NULL;
00074 char global_image_name [1024];
00075 FILE* image_file = NULL;
00076 struct slate_image_header sih;
00077 struct object_heap* heap;
00078 word_t memory_limit = 400 * MB;
00079 word_t young_limit = 5 * MB;
00080 size_t res;
00081 bool_t automaticallyInline = 0;
00082 word_t le_test_ = 1;
00083 char* le_test = (char*)&le_test_;
00084 int i, quiet = 0, verbose = 0, fread_num = 0, quietGC = 1;
00085 #ifndef WIN32
00086 struct sigaction interrupt_action, pipe_ignore_action;
00087 #endif
00088
00089
00090 for (i = 1; i < argc; i++) {
00091 if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
00092 print_usage(argv[0]);
00093 return 0;
00094 } else if ((strcmp(argv[i], "-i") == 0) || (strcmp(argv[i], "--image") == 0)) {
00095 if (++i < argc) {
00096 image_name = argv[i];
00097 } else {
00098 error("You must specify an image filename after -i/--image.");
00099 }
00100 } else if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--version") == 0)) {
00101 fprintf(stderr, "Slate VM\n");
00102
00103 fprintf(stderr, "Build type: %s\n", SLATE_BUILD_TYPE);
00104 fprintf(stderr, "Platform word-size: %d bits; byte-order: %s endian\n", (int)sizeof(word_t)*8, (le_test[0] == 1)? "little" : "big");
00105 return 0;
00106 } else if (strcmp(argv[i], "-mo") == 0) {
00107 memory_limit = memory_string_to_bytes(argv[i+1]);
00108 i++;
00109 } else if (strcmp(argv[i], "-mn") == 0) {
00110 young_limit = memory_string_to_bytes(argv[i+1]);
00111 i++;
00112 } else if (strcmp(argv[i], "-O") == 0) {
00113 automaticallyInline = 1;
00114 } else if (strcmp(argv[i], "-V") == 0) {
00115 quiet = 0;
00116 verbose = 1;
00117 } else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
00118 quiet = 1;
00119 verbose = 0;
00120 } else if (strcmp(argv[i], "-gc") == 0 || strcmp(argv[i], "--show-gc") == 0) {
00121 quietGC = 0;
00122 } else if (strcmp(argv[i], "--") == 0) {
00123
00124 break;
00125 } else {
00126
00127 if (verbose) {
00128 fprintf(stderr, "Illegal argument: %s\n", argv[i]);
00129 }
00130 }
00131 };
00132
00133
00134 if (!image_name && getenv("SLATE_IMAGE")) {
00135 image_name = getenv("SLATE_IMAGE");
00136 quiet = 1;
00137 }
00138
00139
00140 if (!image_name) {
00141 image_name = xstr (SLATE_DEFAULT_IMAGE);
00142 image_file = fopen(image_name, "rb");
00143 if (!image_file) {
00144 sprintf (global_image_name, "%s/%s", xstr (SLATE_DATADIR), xstr (SLATE_DEFAULT_IMAGE));
00145 image_name = (char *)global_image_name;
00146 };
00147 quiet = 1;
00148 };
00149
00150 if (verbose)
00151 fprintf(stderr, "Loading image: %s\n", image_name);
00152
00153 if (!image_file) {
00154 image_file = fopen(image_name, "rb");
00155 };
00156
00157 if (!image_file) {fprintf(stderr, "Open file failed (%d), filename: '%s'\n", errno, image_name); return 1;}
00158
00159
00160 fread_num = fread(&sih.magic, sizeof(sih.magic), 1, image_file); assert(fread_num == 1);
00161 fread_num = fread(&sih.size, sizeof(sih.size), 1, image_file); assert(fread_num == 1);
00162 fread_num = fread(&sih.next_hash, sizeof(sih.next_hash), 1, image_file); assert(fread_num == 1);
00163 fread_num = fread(&sih.special_objects_oop, sizeof(sih.special_objects_oop), 1, image_file); assert(fread_num == 1);
00164 fread_num = fread(&sih.current_dispatch_id, sizeof(sih.current_dispatch_id), 1, image_file); assert(fread_num == 1);
00165
00166 if (sih.size == 0) {
00167 fprintf(stderr, "Image size is zero. You have probably tried to load a file that isn't an image file or a file that is the wrong WORD_SIZE. Run slate without any options to see your build configuration.\n");
00168 return 1;
00169 }
00170
00171 if (sih.magic != SLATE_IMAGE_MAGIC) {
00172 fprintf(stderr, "Magic number (0x%" PRIxPTR ") doesn't match (word_t)0xABCDEF43. Make sure you have a valid slate image and it is the correct endianess. Run slate without arguments to see more info.\n", sih.magic);
00173 fprintf(stderr, "Image filename: '%s'\n", image_name);
00174 return 1;
00175 }
00176
00177 if (memory_limit < sih.size) {
00178 fprintf(stderr, "Slate image cannot fit into base allocated memory size. Use -mo with a greater value\n");
00179 return 1;
00180 }
00181
00182
00183 heap = new object_heap;
00184 memset(heap->delegation_stack, 0, sizeof(heap->delegation_stack));
00185 memset(heap->methodCache, 0, sizeof(heap->methodCache));
00186 memset(heap->memory_areas, 0, sizeof(heap->memory_areas));
00187 memset(heap->memory_sizes, 0, sizeof(heap->memory_sizes));
00188 memset(heap->memory_num_refs, 0, sizeof(heap->memory_num_refs));
00189
00190
00191 if (!heap_initialize(heap, sih.size, memory_limit, young_limit, sih.next_hash, sih.special_objects_oop, sih.current_dispatch_id)) return 1;
00192
00193 heap->automaticallyInline = automaticallyInline;
00194 heap->quiet = quiet;
00195 heap->quietGC = quietGC;
00196 heap->envp = envp;
00197 if (!heap->quiet) {
00198 printf("Old Memory size: %" PRIdPTR " bytes\n", memory_limit);
00199 printf("New Memory size: %" PRIdPTR " bytes\n", young_limit);
00200 printf("Image size: %" PRIdPTR " bytes\n", sih.size);
00201 }
00202
00203
00204 if ((res = fread(heap->memoryOld, 1, sih.size, image_file)) != (size_t)sih.size) {
00205 fprintf(stderr, "Error fread()ing image. Got %" PRIuPTR "u, expected %" PRIuPTR "u.\n", res, sih.size);
00206 return 1;
00207 }
00208
00209
00210 fclose(image_file);
00211
00212 adjust_oop_pointers_from(heap, (word_t)heap->memoryOld, heap->memoryOld, heap->memoryOldSize);
00213 heap_zero_pin_counts_from(heap, heap->memoryOld, heap->memoryOldSize);
00214 heap->stackBottom = &heap;
00215 heap->argcSaved = argc;
00216 heap->argvSaved = argv;
00217 heap->currentlyProfiling = 0;
00218 #ifdef WIN32
00219 signal(SIGINT, slate_interrupt_handler);
00220 #else
00221 interrupt_action.sa_handler = slate_interrupt_handler;
00222 interrupt_action.sa_flags = 0;
00223 sigemptyset(&interrupt_action.sa_mask);
00224 sigaction(SIGINT, &interrupt_action, NULL);
00225
00226
00227 pipe_ignore_action.sa_handler = SIG_IGN;
00228 pipe_ignore_action.sa_flags = 0;
00229 sigemptyset(&pipe_ignore_action.sa_mask);
00230 sigaction(SIGPIPE, &pipe_ignore_action, NULL);
00231 #endif
00232
00233
00234 file_module_init(heap);
00235 socket_module_init(heap);
00236 dir_module_init(heap);
00237 memarea_module_init(heap);
00238
00239 interpret(heap);
00240
00241 heap_close(heap);
00242
00243 return 0;
00244 }