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 #ifndef V8_STUB_CACHE_H_
00029 #define V8_STUB_CACHE_H_
00030
00031 #include "macro-assembler.h"
00032
00033 namespace v8 { namespace internal {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 class SCTableReference;
00045
00046 class StubCache : public AllStatic {
00047 public:
00048 struct Entry {
00049 String* key;
00050 Code* value;
00051 };
00052
00053
00054 static void Initialize(bool create_heap_objects);
00055
00056
00057
00058 static Object* ComputeLoadField(String* name,
00059 JSObject* receiver,
00060 JSObject* holder,
00061 int field_index);
00062
00063 static Object* ComputeLoadCallback(String* name,
00064 JSObject* receiver,
00065 JSObject* holder,
00066 AccessorInfo* callback);
00067
00068 static Object* ComputeLoadConstant(String* name,
00069 JSObject* receiver,
00070 JSObject* holder,
00071 Object* value);
00072
00073 static Object* ComputeLoadInterceptor(String* name,
00074 JSObject* receiver,
00075 JSObject* holder);
00076
00077 static Object* ComputeLoadNormal(String* name, JSObject* receiver);
00078
00079
00080
00081
00082 static Object* ComputeKeyedLoadField(String* name,
00083 JSObject* receiver,
00084 JSObject* holder,
00085 int field_index);
00086
00087 static Object* ComputeKeyedLoadCallback(String* name,
00088 JSObject* receiver,
00089 JSObject* holder,
00090 AccessorInfo* callback);
00091
00092 static Object* ComputeKeyedLoadConstant(String* name, JSObject* receiver,
00093 JSObject* holder, Object* value);
00094
00095 static Object* ComputeKeyedLoadInterceptor(String* name,
00096 JSObject* receiver,
00097 JSObject* holder);
00098
00099 static Object* ComputeKeyedLoadArrayLength(String* name, JSArray* receiver);
00100
00101 static Object* ComputeKeyedLoadStringLength(String* name,
00102 String* receiver);
00103
00104 static Object* ComputeKeyedLoadFunctionPrototype(String* name,
00105 JSFunction* receiver);
00106
00107
00108
00109 static Object* ComputeStoreField(String* name,
00110 JSObject* receiver,
00111 int field_index,
00112 Map* transition = NULL);
00113
00114 static Object* ComputeStoreCallback(String* name,
00115 JSObject* receiver,
00116 AccessorInfo* callback);
00117
00118 static Object* ComputeStoreInterceptor(String* name, JSObject* receiver);
00119
00120
00121
00122 static Object* ComputeKeyedStoreField(String* name,
00123 JSObject* receiver,
00124 int field_index,
00125 Map* transition = NULL);
00126
00127
00128
00129 static Object* ComputeCallField(int argc,
00130 String* name,
00131 Object* object,
00132 JSObject* holder,
00133 int index);
00134
00135 static Object* ComputeCallConstant(int argc,
00136 String* name,
00137 Object* object,
00138 JSObject* holder,
00139 JSFunction* function);
00140
00141 static Object* ComputeCallNormal(int argc, String* name, JSObject* receiver);
00142
00143 static Object* ComputeCallInterceptor(int argc,
00144 String* name,
00145 Object* object,
00146 JSObject* holder);
00147
00148
00149
00150 static Object* ComputeCallInitialize(int argc);
00151 static Object* ComputeCallPreMonomorphic(int argc);
00152 static Object* ComputeCallNormal(int argc);
00153 static Object* ComputeCallMegamorphic(int argc);
00154 static Object* ComputeCallMiss(int argc);
00155
00156
00157 static Code* FindCallInitialize(int argc);
00158
00159 static Object* ComputeCallDebugBreak(int argc);
00160 static Object* ComputeCallDebugPrepareStepIn(int argc);
00161
00162 static Object* ComputeLazyCompile(int argc);
00163
00164
00165
00166 static Code* Set(String* name, Map* map, Code* code);
00167
00168
00169 static void Clear();
00170
00171
00172 static void GenerateMiss(MacroAssembler* masm);
00173
00174
00175 static void GenerateProbe(MacroAssembler* masm,
00176 Code::Flags flags,
00177 Register receiver,
00178 Register name,
00179 Register scratch);
00180
00181 enum Table {
00182 kPrimary,
00183 kSecondary
00184 };
00185
00186 private:
00187 friend class SCTableReference;
00188 static const int kPrimaryTableSize = 2048;
00189 static const int kSecondaryTableSize = 512;
00190 static Entry primary_[];
00191 static Entry secondary_[];
00192
00193
00194 static int PrimaryOffset(String* name, Code::Flags flags, Map* map) {
00195
00196
00197
00198
00199 ASSERT(kHeapObjectTagSize == String::kHashShift);
00200
00201 ASSERT(name->HasHashCode());
00202 uint32_t field = name->length_field();
00203
00204 uint32_t key = (reinterpret_cast<uint32_t>(map) + field) ^ flags;
00205 return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
00206 }
00207
00208 static int SecondaryOffset(String* name, Code::Flags flags, int seed) {
00209
00210 uint32_t key = seed - reinterpret_cast<uint32_t>(name) + flags;
00211 return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
00212 }
00213
00214
00215
00216
00217 static Entry* entry(Entry* table, int offset) {
00218 return reinterpret_cast<Entry*>(
00219 reinterpret_cast<Address>(table) + (offset << 1));
00220 }
00221 };
00222
00223
00224 class SCTableReference {
00225 public:
00226 static SCTableReference keyReference(StubCache::Table table) {
00227 return SCTableReference(
00228 reinterpret_cast<Address>(&first_entry(table)->key));
00229 }
00230
00231
00232 static SCTableReference valueReference(StubCache::Table table) {
00233 return SCTableReference(
00234 reinterpret_cast<Address>(&first_entry(table)->value));
00235 }
00236
00237 Address address() const { return address_; }
00238
00239 private:
00240 explicit SCTableReference(Address address) : address_(address) {}
00241
00242 static StubCache::Entry* first_entry(StubCache::Table table) {
00243 switch (table) {
00244 case StubCache::kPrimary: return StubCache::primary_;
00245 case StubCache::kSecondary: return StubCache::secondary_;
00246 }
00247 UNREACHABLE();
00248 return NULL;
00249 }
00250
00251 Address address_;
00252 };
00253
00254
00255
00256
00257
00258 Object* LoadCallbackProperty(Arguments args);
00259 Object* StoreCallbackProperty(Arguments args);
00260
00261
00262
00263 Object* LoadInterceptorProperty(Arguments args);
00264 Object* StoreInterceptorProperty(Arguments args);
00265 Object* CallInterceptorProperty(Arguments args);
00266
00267
00268
00269 Handle<Code> ComputeCallMiss(int argc);
00270
00271
00272
00273 class StubCompiler BASE_EMBEDDED {
00274 public:
00275 enum CheckType {
00276 RECEIVER_MAP_CHECK,
00277 STRING_CHECK,
00278 NUMBER_CHECK,
00279 BOOLEAN_CHECK,
00280 JSARRAY_HAS_FAST_ELEMENTS_CHECK
00281 };
00282
00283 StubCompiler() : masm_(NULL, 256) { }
00284
00285 Object* CompileCallInitialize(Code::Flags flags);
00286 Object* CompileCallPreMonomorphic(Code::Flags flags);
00287 Object* CompileCallNormal(Code::Flags flags);
00288 Object* CompileCallMegamorphic(Code::Flags flags);
00289 Object* CompileCallMiss(Code::Flags flags);
00290 Object* CompileCallDebugBreak(Code::Flags flags);
00291 Object* CompileCallDebugPrepareStepIn(Code::Flags flags);
00292 Object* CompileLazyCompile(Code::Flags flags);
00293
00294
00295 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
00296 int index,
00297 Register prototype);
00298 static void GenerateFastPropertyLoad(MacroAssembler* masm,
00299 Register dst, Register src,
00300 JSObject* holder, int index);
00301 static void GenerateLoadField(MacroAssembler* masm,
00302 JSObject* object,
00303 JSObject* holder,
00304 Register receiver,
00305 Register scratch1,
00306 Register scratch2,
00307 int index,
00308 Label* miss_label);
00309 static void GenerateLoadCallback(MacroAssembler* masm,
00310 JSObject* object,
00311 JSObject* holder,
00312 Register receiver,
00313 Register name,
00314 Register scratch1,
00315 Register scratch2,
00316 AccessorInfo* callback,
00317 Label* miss_label);
00318 static void GenerateLoadConstant(MacroAssembler* masm,
00319 JSObject* object,
00320 JSObject* holder,
00321 Register receiver,
00322 Register scratch1,
00323 Register scratch2,
00324 Object* value,
00325 Label* miss_label);
00326 static void GenerateLoadInterceptor(MacroAssembler* masm,
00327 JSObject* object,
00328 JSObject* holder,
00329 Register receiver,
00330 Register name,
00331 Register scratch1,
00332 Register scratch2,
00333 Label* miss_label);
00334 static void GenerateLoadArrayLength(MacroAssembler* masm,
00335 Register receiver,
00336 Register scratch,
00337 Label* miss_label);
00338 static void GenerateLoadStringLength(MacroAssembler* masm,
00339 Register receiver,
00340 Register scratch,
00341 Label* miss_label);
00342 static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
00343 Register receiver,
00344 Register scratch1,
00345 Register scratch2,
00346 Label* miss_label);
00347 static void GenerateStoreField(MacroAssembler* masm,
00348 Builtins::Name storage_extend,
00349 JSObject* object,
00350 int index,
00351 Map* transition,
00352 Register receiver_reg,
00353 Register name_reg,
00354 Register scratch,
00355 Label* miss_label);
00356 static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);
00357
00358 protected:
00359 Object* GetCodeWithFlags(Code::Flags flags);
00360
00361 MacroAssembler* masm() { return &masm_; }
00362
00363 private:
00364 MacroAssembler masm_;
00365 };
00366
00367
00368 class LoadStubCompiler: public StubCompiler {
00369 public:
00370 Object* CompileLoadField(JSObject* object, JSObject* holder, int index);
00371 Object* CompileLoadCallback(JSObject* object,
00372 JSObject* holder,
00373 AccessorInfo* callback);
00374 Object* CompileLoadConstant(JSObject* object,
00375 JSObject* holder,
00376 Object* value);
00377 Object* CompileLoadInterceptor(JSObject* object,
00378 JSObject* holder,
00379 String* name);
00380
00381 private:
00382 Object* GetCode(PropertyType);
00383 };
00384
00385
00386 class KeyedLoadStubCompiler: public StubCompiler {
00387 public:
00388 Object* CompileLoadField(String* name,
00389 JSObject* object,
00390 JSObject* holder,
00391 int index);
00392 Object* CompileLoadCallback(String* name,
00393 JSObject* object,
00394 JSObject* holder,
00395 AccessorInfo* callback);
00396 Object* CompileLoadConstant(String* name,
00397 JSObject* object,
00398 JSObject* holder,
00399 Object* value);
00400 Object* CompileLoadInterceptor(JSObject* object,
00401 JSObject* holder,
00402 String* name);
00403 Object* CompileLoadArrayLength(String* name);
00404 Object* CompileLoadStringLength(String* name);
00405 Object* CompileLoadFunctionPrototype(String* name);
00406
00407 private:
00408 Object* GetCode(PropertyType);
00409 };
00410
00411
00412 class StoreStubCompiler: public StubCompiler {
00413 public:
00414 Object* CompileStoreField(JSObject* object,
00415 int index,
00416 Map* transition,
00417 String* name);
00418 Object* CompileStoreCallback(JSObject* object,
00419 AccessorInfo* callbacks,
00420 String* name);
00421 Object* CompileStoreInterceptor(JSObject* object, String* name);
00422
00423 private:
00424 Object* GetCode(PropertyType type);
00425 };
00426
00427
00428 class KeyedStoreStubCompiler: public StubCompiler {
00429 public:
00430 Object* CompileStoreField(JSObject* object,
00431 int index,
00432 Map* transition,
00433 String* name);
00434
00435 private:
00436 Object* GetCode(PropertyType type);
00437 };
00438
00439
00440 class CallStubCompiler: public StubCompiler {
00441 public:
00442 explicit CallStubCompiler(int argc) : arguments_(argc) { }
00443
00444 Object* CompileCallField(Object* object, JSObject* holder, int index);
00445 Object* CompileCallConstant(Object* object,
00446 JSObject* holder,
00447 JSFunction* function,
00448 CheckType check);
00449 Object* CompileCallInterceptor(Object* object,
00450 JSObject* holder,
00451 String* name);
00452
00453 private:
00454 const ParameterCount arguments_;
00455
00456 const ParameterCount& arguments() { return arguments_; }
00457
00458 Object* GetCode(PropertyType type);
00459 };
00460
00461
00462 } }
00463
00464 #endif // V8_STUB_CACHE_H_