| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 // name specific if there are global objects involved. | 112 // name specific if there are global objects involved. |
| 113 Code::Flags flags = | 113 Code::Flags flags = |
| 114 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); | 114 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); |
| 115 Object* code = receiver->map()->FindInCodeCache(cache_name, flags); | 115 Object* code = receiver->map()->FindInCodeCache(cache_name, flags); |
| 116 if (code->IsUndefined()) { | 116 if (code->IsUndefined()) { |
| 117 LoadStubCompiler compiler; | 117 LoadStubCompiler compiler; |
| 118 code = compiler.CompileLoadNonexistent(cache_name, receiver, last); | 118 code = compiler.CompileLoadNonexistent(cache_name, receiver, last); |
| 119 if (code->IsFailure()) return code; | 119 if (code->IsFailure()) return code; |
| 120 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name)); | 120 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name)); |
| 121 Object* result = | 121 Object* result = |
| 122 receiver->map()->UpdateCodeCache(cache_name, Code::cast(code)); | 122 receiver->UpdateMapCodeCache(cache_name, Code::cast(code)); |
| 123 if (result->IsFailure()) return result; | 123 if (result->IsFailure()) return result; |
| 124 } | 124 } |
| 125 return code; | 125 return code; |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 Object* StubCache::ComputeLoadField(String* name, | 129 Object* StubCache::ComputeLoadField(String* name, |
| 130 JSObject* receiver, | 130 JSObject* receiver, |
| 131 JSObject* holder, | 131 JSObject* holder, |
| 132 int field_index) { | 132 int field_index) { |
| 133 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 133 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 134 Map* map = receiver->map(); | |
| 135 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); | 134 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); |
| 136 Object* code = map->FindInCodeCache(name, flags); | 135 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 137 if (code->IsUndefined()) { | 136 if (code->IsUndefined()) { |
| 138 LoadStubCompiler compiler; | 137 LoadStubCompiler compiler; |
| 139 code = compiler.CompileLoadField(receiver, holder, field_index, name); | 138 code = compiler.CompileLoadField(receiver, holder, field_index, name); |
| 140 if (code->IsFailure()) return code; | 139 if (code->IsFailure()) return code; |
| 141 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 140 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 142 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 141 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 143 if (result->IsFailure()) return result; | 142 if (result->IsFailure()) return result; |
| 144 } | 143 } |
| 145 return code; | 144 return code; |
| 146 } | 145 } |
| 147 | 146 |
| 148 | 147 |
| 149 Object* StubCache::ComputeLoadCallback(String* name, | 148 Object* StubCache::ComputeLoadCallback(String* name, |
| 150 JSObject* receiver, | 149 JSObject* receiver, |
| 151 JSObject* holder, | 150 JSObject* holder, |
| 152 AccessorInfo* callback) { | 151 AccessorInfo* callback) { |
| 153 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 152 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
| 154 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 153 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 155 Map* map = receiver->map(); | |
| 156 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); | 154 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); |
| 157 Object* code = map->FindInCodeCache(name, flags); | 155 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 158 if (code->IsUndefined()) { | 156 if (code->IsUndefined()) { |
| 159 LoadStubCompiler compiler; | 157 LoadStubCompiler compiler; |
| 160 code = compiler.CompileLoadCallback(name, receiver, holder, callback); | 158 code = compiler.CompileLoadCallback(name, receiver, holder, callback); |
| 161 if (code->IsFailure()) return code; | 159 if (code->IsFailure()) return code; |
| 162 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 160 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 163 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 161 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 164 if (result->IsFailure()) return result; | 162 if (result->IsFailure()) return result; |
| 165 } | 163 } |
| 166 return code; | 164 return code; |
| 167 } | 165 } |
| 168 | 166 |
| 169 | 167 |
| 170 Object* StubCache::ComputeLoadConstant(String* name, | 168 Object* StubCache::ComputeLoadConstant(String* name, |
| 171 JSObject* receiver, | 169 JSObject* receiver, |
| 172 JSObject* holder, | 170 JSObject* holder, |
| 173 Object* value) { | 171 Object* value) { |
| 174 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 172 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 175 Map* map = receiver->map(); | |
| 176 Code::Flags flags = | 173 Code::Flags flags = |
| 177 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); | 174 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); |
| 178 Object* code = map->FindInCodeCache(name, flags); | 175 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 179 if (code->IsUndefined()) { | 176 if (code->IsUndefined()) { |
| 180 LoadStubCompiler compiler; | 177 LoadStubCompiler compiler; |
| 181 code = compiler.CompileLoadConstant(receiver, holder, value, name); | 178 code = compiler.CompileLoadConstant(receiver, holder, value, name); |
| 182 if (code->IsFailure()) return code; | 179 if (code->IsFailure()) return code; |
| 183 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 180 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 184 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 181 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 185 if (result->IsFailure()) return result; | 182 if (result->IsFailure()) return result; |
| 186 } | 183 } |
| 187 return code; | 184 return code; |
| 188 } | 185 } |
| 189 | 186 |
| 190 | 187 |
| 191 Object* StubCache::ComputeLoadInterceptor(String* name, | 188 Object* StubCache::ComputeLoadInterceptor(String* name, |
| 192 JSObject* receiver, | 189 JSObject* receiver, |
| 193 JSObject* holder) { | 190 JSObject* holder) { |
| 194 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 191 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 195 Map* map = receiver->map(); | |
| 196 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); | 192 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); |
| 197 Object* code = map->FindInCodeCache(name, flags); | 193 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 198 if (code->IsUndefined()) { | 194 if (code->IsUndefined()) { |
| 199 LoadStubCompiler compiler; | 195 LoadStubCompiler compiler; |
| 200 code = compiler.CompileLoadInterceptor(receiver, holder, name); | 196 code = compiler.CompileLoadInterceptor(receiver, holder, name); |
| 201 if (code->IsFailure()) return code; | 197 if (code->IsFailure()) return code; |
| 202 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 198 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 203 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 199 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 204 if (result->IsFailure()) return result; | 200 if (result->IsFailure()) return result; |
| 205 } | 201 } |
| 206 return code; | 202 return code; |
| 207 } | 203 } |
| 208 | 204 |
| 209 | 205 |
| 210 Object* StubCache::ComputeLoadNormal() { | 206 Object* StubCache::ComputeLoadNormal() { |
| 211 return Builtins::builtin(Builtins::LoadIC_Normal); | 207 return Builtins::builtin(Builtins::LoadIC_Normal); |
| 212 } | 208 } |
| 213 | 209 |
| 214 | 210 |
| 215 Object* StubCache::ComputeLoadGlobal(String* name, | 211 Object* StubCache::ComputeLoadGlobal(String* name, |
| 216 JSObject* receiver, | 212 JSObject* receiver, |
| 217 GlobalObject* holder, | 213 GlobalObject* holder, |
| 218 JSGlobalPropertyCell* cell, | 214 JSGlobalPropertyCell* cell, |
| 219 bool is_dont_delete) { | 215 bool is_dont_delete) { |
| 220 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 216 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 221 Map* map = receiver->map(); | |
| 222 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); | 217 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
| 223 Object* code = map->FindInCodeCache(name, flags); | 218 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 224 if (code->IsUndefined()) { | 219 if (code->IsUndefined()) { |
| 225 LoadStubCompiler compiler; | 220 LoadStubCompiler compiler; |
| 226 code = compiler.CompileLoadGlobal(receiver, | 221 code = compiler.CompileLoadGlobal(receiver, |
| 227 holder, | 222 holder, |
| 228 cell, | 223 cell, |
| 229 name, | 224 name, |
| 230 is_dont_delete); | 225 is_dont_delete); |
| 231 if (code->IsFailure()) return code; | 226 if (code->IsFailure()) return code; |
| 232 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); | 227 PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 233 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 228 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 234 if (result->IsFailure()) return result; | 229 if (result->IsFailure()) return result; |
| 235 } | 230 } |
| 236 return code; | 231 return code; |
| 237 } | 232 } |
| 238 | 233 |
| 239 | 234 |
| 240 Object* StubCache::ComputeKeyedLoadField(String* name, | 235 Object* StubCache::ComputeKeyedLoadField(String* name, |
| 241 JSObject* receiver, | 236 JSObject* receiver, |
| 242 JSObject* holder, | 237 JSObject* holder, |
| 243 int field_index) { | 238 int field_index) { |
| 244 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 239 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 245 Map* map = receiver->map(); | |
| 246 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); | 240 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); |
| 247 Object* code = map->FindInCodeCache(name, flags); | 241 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 248 if (code->IsUndefined()) { | 242 if (code->IsUndefined()) { |
| 249 KeyedLoadStubCompiler compiler; | 243 KeyedLoadStubCompiler compiler; |
| 250 code = compiler.CompileLoadField(name, receiver, holder, field_index); | 244 code = compiler.CompileLoadField(name, receiver, holder, field_index); |
| 251 if (code->IsFailure()) return code; | 245 if (code->IsFailure()) return code; |
| 252 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 246 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 253 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 247 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 254 if (result->IsFailure()) return result; | 248 if (result->IsFailure()) return result; |
| 255 } | 249 } |
| 256 return code; | 250 return code; |
| 257 } | 251 } |
| 258 | 252 |
| 259 | 253 |
| 260 Object* StubCache::ComputeKeyedLoadConstant(String* name, | 254 Object* StubCache::ComputeKeyedLoadConstant(String* name, |
| 261 JSObject* receiver, | 255 JSObject* receiver, |
| 262 JSObject* holder, | 256 JSObject* holder, |
| 263 Object* value) { | 257 Object* value) { |
| 264 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 258 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 265 Map* map = receiver->map(); | |
| 266 Code::Flags flags = | 259 Code::Flags flags = |
| 267 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); | 260 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); |
| 268 Object* code = map->FindInCodeCache(name, flags); | 261 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 269 if (code->IsUndefined()) { | 262 if (code->IsUndefined()) { |
| 270 KeyedLoadStubCompiler compiler; | 263 KeyedLoadStubCompiler compiler; |
| 271 code = compiler.CompileLoadConstant(name, receiver, holder, value); | 264 code = compiler.CompileLoadConstant(name, receiver, holder, value); |
| 272 if (code->IsFailure()) return code; | 265 if (code->IsFailure()) return code; |
| 273 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 266 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 274 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 267 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 275 if (result->IsFailure()) return result; | 268 if (result->IsFailure()) return result; |
| 276 } | 269 } |
| 277 return code; | 270 return code; |
| 278 } | 271 } |
| 279 | 272 |
| 280 | 273 |
| 281 Object* StubCache::ComputeKeyedLoadInterceptor(String* name, | 274 Object* StubCache::ComputeKeyedLoadInterceptor(String* name, |
| 282 JSObject* receiver, | 275 JSObject* receiver, |
| 283 JSObject* holder) { | 276 JSObject* holder) { |
| 284 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 277 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 285 Map* map = receiver->map(); | |
| 286 Code::Flags flags = | 278 Code::Flags flags = |
| 287 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); | 279 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); |
| 288 Object* code = map->FindInCodeCache(name, flags); | 280 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 289 if (code->IsUndefined()) { | 281 if (code->IsUndefined()) { |
| 290 KeyedLoadStubCompiler compiler; | 282 KeyedLoadStubCompiler compiler; |
| 291 code = compiler.CompileLoadInterceptor(receiver, holder, name); | 283 code = compiler.CompileLoadInterceptor(receiver, holder, name); |
| 292 if (code->IsFailure()) return code; | 284 if (code->IsFailure()) return code; |
| 293 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 285 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 294 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 286 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 295 if (result->IsFailure()) return result; | 287 if (result->IsFailure()) return result; |
| 296 } | 288 } |
| 297 return code; | 289 return code; |
| 298 } | 290 } |
| 299 | 291 |
| 300 | 292 |
| 301 Object* StubCache::ComputeKeyedLoadCallback(String* name, | 293 Object* StubCache::ComputeKeyedLoadCallback(String* name, |
| 302 JSObject* receiver, | 294 JSObject* receiver, |
| 303 JSObject* holder, | 295 JSObject* holder, |
| 304 AccessorInfo* callback) { | 296 AccessorInfo* callback) { |
| 305 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); | 297 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
| 306 Map* map = receiver->map(); | |
| 307 Code::Flags flags = | 298 Code::Flags flags = |
| 308 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 299 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
| 309 Object* code = map->FindInCodeCache(name, flags); | 300 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 310 if (code->IsUndefined()) { | 301 if (code->IsUndefined()) { |
| 311 KeyedLoadStubCompiler compiler; | 302 KeyedLoadStubCompiler compiler; |
| 312 code = compiler.CompileLoadCallback(name, receiver, holder, callback); | 303 code = compiler.CompileLoadCallback(name, receiver, holder, callback); |
| 313 if (code->IsFailure()) return code; | 304 if (code->IsFailure()) return code; |
| 314 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 305 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 315 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 306 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 316 if (result->IsFailure()) return result; | 307 if (result->IsFailure()) return result; |
| 317 } | 308 } |
| 318 return code; | 309 return code; |
| 319 } | 310 } |
| 320 | 311 |
| 321 | 312 |
| 322 | 313 |
| 323 Object* StubCache::ComputeKeyedLoadArrayLength(String* name, | 314 Object* StubCache::ComputeKeyedLoadArrayLength(String* name, |
| 324 JSArray* receiver) { | 315 JSArray* receiver) { |
| 325 Code::Flags flags = | 316 Code::Flags flags = |
| 326 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 317 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
| 327 ASSERT(receiver->IsJSObject()); | 318 ASSERT(receiver->IsJSObject()); |
| 328 Map* map = receiver->map(); | 319 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 329 Object* code = map->FindInCodeCache(name, flags); | |
| 330 if (code->IsUndefined()) { | 320 if (code->IsUndefined()) { |
| 331 KeyedLoadStubCompiler compiler; | 321 KeyedLoadStubCompiler compiler; |
| 332 code = compiler.CompileLoadArrayLength(name); | 322 code = compiler.CompileLoadArrayLength(name); |
| 333 if (code->IsFailure()) return code; | 323 if (code->IsFailure()) return code; |
| 334 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 324 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 335 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 325 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 336 if (result->IsFailure()) return result; | 326 if (result->IsFailure()) return result; |
| 337 } | 327 } |
| 338 return code; | 328 return code; |
| 339 } | 329 } |
| 340 | 330 |
| 341 | 331 |
| 342 Object* StubCache::ComputeKeyedLoadStringLength(String* name, | 332 Object* StubCache::ComputeKeyedLoadStringLength(String* name, |
| 343 String* receiver) { | 333 String* receiver) { |
| 344 Code::Flags flags = | 334 Code::Flags flags = |
| 345 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 335 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
| 346 Map* map = receiver->map(); | 336 Map* map = receiver->map(); |
| 347 Object* code = map->FindInCodeCache(name, flags); | 337 Object* code = map->FindInCodeCache(name, flags); |
| 348 if (code->IsUndefined()) { | 338 if (code->IsUndefined()) { |
| 349 KeyedLoadStubCompiler compiler; | 339 KeyedLoadStubCompiler compiler; |
| 350 code = compiler.CompileLoadStringLength(name); | 340 code = compiler.CompileLoadStringLength(name); |
| 351 if (code->IsFailure()) return code; | 341 if (code->IsFailure()) return code; |
| 352 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 342 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 353 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 343 Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
| 354 if (result->IsFailure()) return result; | 344 if (result->IsFailure()) return result; |
| 355 } | 345 } |
| 356 return code; | 346 return code; |
| 357 } | 347 } |
| 358 | 348 |
| 359 | 349 |
| 360 Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name, | 350 Object* StubCache::ComputeKeyedLoadFunctionPrototype(String* name, |
| 361 JSFunction* receiver) { | 351 JSFunction* receiver) { |
| 362 Code::Flags flags = | 352 Code::Flags flags = |
| 363 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); | 353 Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
| 364 Map* map = receiver->map(); | 354 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 365 Object* code = map->FindInCodeCache(name, flags); | |
| 366 if (code->IsUndefined()) { | 355 if (code->IsUndefined()) { |
| 367 KeyedLoadStubCompiler compiler; | 356 KeyedLoadStubCompiler compiler; |
| 368 code = compiler.CompileLoadFunctionPrototype(name); | 357 code = compiler.CompileLoadFunctionPrototype(name); |
| 369 if (code->IsFailure()) return code; | 358 if (code->IsFailure()) return code; |
| 370 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); | 359 PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
| 371 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 360 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 372 if (result->IsFailure()) return result; | 361 if (result->IsFailure()) return result; |
| 373 } | 362 } |
| 374 return code; | 363 return code; |
| 375 } | 364 } |
| 376 | 365 |
| 377 | 366 |
| 378 Object* StubCache::ComputeStoreField(String* name, | 367 Object* StubCache::ComputeStoreField(String* name, |
| 379 JSObject* receiver, | 368 JSObject* receiver, |
| 380 int field_index, | 369 int field_index, |
| 381 Map* transition) { | 370 Map* transition) { |
| 382 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; | 371 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; |
| 383 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type); | 372 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, type); |
| 384 Object* code = receiver->map()->FindInCodeCache(name, flags); | 373 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 385 if (code->IsUndefined()) { | 374 if (code->IsUndefined()) { |
| 386 StoreStubCompiler compiler; | 375 StoreStubCompiler compiler; |
| 387 code = compiler.CompileStoreField(receiver, field_index, transition, name); | 376 code = compiler.CompileStoreField(receiver, field_index, transition, name); |
| 388 if (code->IsFailure()) return code; | 377 if (code->IsFailure()) return code; |
| 389 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 378 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
| 390 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 379 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 391 if (result->IsFailure()) return result; | 380 if (result->IsFailure()) return result; |
| 392 } | 381 } |
| 393 return code; | 382 return code; |
| 394 } | 383 } |
| 395 | 384 |
| 396 | 385 |
| 397 Object* StubCache::ComputeStoreNormal() { | 386 Object* StubCache::ComputeStoreNormal() { |
| 398 return Builtins::builtin(Builtins::StoreIC_Normal); | 387 return Builtins::builtin(Builtins::StoreIC_Normal); |
| 399 } | 388 } |
| 400 | 389 |
| 401 | 390 |
| 402 Object* StubCache::ComputeStoreGlobal(String* name, | 391 Object* StubCache::ComputeStoreGlobal(String* name, |
| 403 GlobalObject* receiver, | 392 GlobalObject* receiver, |
| 404 JSGlobalPropertyCell* cell) { | 393 JSGlobalPropertyCell* cell) { |
| 405 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); | 394 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); |
| 406 Object* code = receiver->map()->FindInCodeCache(name, flags); | 395 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 407 if (code->IsUndefined()) { | 396 if (code->IsUndefined()) { |
| 408 StoreStubCompiler compiler; | 397 StoreStubCompiler compiler; |
| 409 code = compiler.CompileStoreGlobal(receiver, cell, name); | 398 code = compiler.CompileStoreGlobal(receiver, cell, name); |
| 410 if (code->IsFailure()) return code; | 399 if (code->IsFailure()) return code; |
| 411 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 400 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
| 412 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 401 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 413 if (result->IsFailure()) return result; | 402 if (result->IsFailure()) return result; |
| 414 } | 403 } |
| 415 return code; | 404 return code; |
| 416 } | 405 } |
| 417 | 406 |
| 418 | 407 |
| 419 Object* StubCache::ComputeStoreCallback(String* name, | 408 Object* StubCache::ComputeStoreCallback(String* name, |
| 420 JSObject* receiver, | 409 JSObject* receiver, |
| 421 AccessorInfo* callback) { | 410 AccessorInfo* callback) { |
| 422 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | 411 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); |
| 423 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS); | 412 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS); |
| 424 Object* code = receiver->map()->FindInCodeCache(name, flags); | 413 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 425 if (code->IsUndefined()) { | 414 if (code->IsUndefined()) { |
| 426 StoreStubCompiler compiler; | 415 StoreStubCompiler compiler; |
| 427 code = compiler.CompileStoreCallback(receiver, callback, name); | 416 code = compiler.CompileStoreCallback(receiver, callback, name); |
| 428 if (code->IsFailure()) return code; | 417 if (code->IsFailure()) return code; |
| 429 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 418 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
| 430 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 419 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 431 if (result->IsFailure()) return result; | 420 if (result->IsFailure()) return result; |
| 432 } | 421 } |
| 433 return code; | 422 return code; |
| 434 } | 423 } |
| 435 | 424 |
| 436 | 425 |
| 437 Object* StubCache::ComputeStoreInterceptor(String* name, | 426 Object* StubCache::ComputeStoreInterceptor(String* name, |
| 438 JSObject* receiver) { | 427 JSObject* receiver) { |
| 439 Code::Flags flags = | 428 Code::Flags flags = |
| 440 Code::ComputeMonomorphicFlags(Code::STORE_IC, INTERCEPTOR); | 429 Code::ComputeMonomorphicFlags(Code::STORE_IC, INTERCEPTOR); |
| 441 Object* code = receiver->map()->FindInCodeCache(name, flags); | 430 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 442 if (code->IsUndefined()) { | 431 if (code->IsUndefined()) { |
| 443 StoreStubCompiler compiler; | 432 StoreStubCompiler compiler; |
| 444 code = compiler.CompileStoreInterceptor(receiver, name); | 433 code = compiler.CompileStoreInterceptor(receiver, name); |
| 445 if (code->IsFailure()) return code; | 434 if (code->IsFailure()) return code; |
| 446 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 435 PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
| 447 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 436 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 448 if (result->IsFailure()) return result; | 437 if (result->IsFailure()) return result; |
| 449 } | 438 } |
| 450 return code; | 439 return code; |
| 451 } | 440 } |
| 452 | 441 |
| 453 | 442 |
| 454 Object* StubCache::ComputeKeyedStoreField(String* name, JSObject* receiver, | 443 Object* StubCache::ComputeKeyedStoreField(String* name, JSObject* receiver, |
| 455 int field_index, Map* transition) { | 444 int field_index, Map* transition) { |
| 456 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; | 445 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; |
| 457 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); | 446 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); |
| 458 Object* code = receiver->map()->FindInCodeCache(name, flags); | 447 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 459 if (code->IsUndefined()) { | 448 if (code->IsUndefined()) { |
| 460 KeyedStoreStubCompiler compiler; | 449 KeyedStoreStubCompiler compiler; |
| 461 code = compiler.CompileStoreField(receiver, field_index, transition, name); | 450 code = compiler.CompileStoreField(receiver, field_index, transition, name); |
| 462 if (code->IsFailure()) return code; | 451 if (code->IsFailure()) return code; |
| 463 PROFILE(CodeCreateEvent( | 452 PROFILE(CodeCreateEvent( |
| 464 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name)); | 453 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name)); |
| 465 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 454 Object* result = receiver->UpdateMapCodeCache(name, Code::cast(code)); |
| 466 if (result->IsFailure()) return result; | 455 if (result->IsFailure()) return result; |
| 467 } | 456 } |
| 468 return code; | 457 return code; |
| 469 } | 458 } |
| 470 | 459 |
| 471 #define CALL_LOGGER_TAG(kind, type) \ | 460 #define CALL_LOGGER_TAG(kind, type) \ |
| 472 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 461 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 473 | 462 |
| 474 Object* StubCache::ComputeCallConstant(int argc, | 463 Object* StubCache::ComputeCallConstant(int argc, |
| 475 InLoopFlag in_loop, | 464 InLoopFlag in_loop, |
| 476 Code::Kind kind, | 465 Code::Kind kind, |
| 477 String* name, | 466 String* name, |
| 478 Object* object, | 467 Object* object, |
| 479 JSObject* holder, | 468 JSObject* holder, |
| 480 JSFunction* function) { | 469 JSFunction* function) { |
| 481 // Compute the check type and the map. | 470 // Compute the check type and the map. |
| 482 InlineCacheHolderFlag cache_holder = | 471 InlineCacheHolderFlag cache_holder = |
| 483 IC::GetCodeCacheForObject(object, holder); | 472 IC::GetCodeCacheForObject(object, holder); |
| 484 Map* map = IC::GetCodeCacheMap(object, cache_holder); | 473 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
| 485 | 474 |
| 486 // Compute check type based on receiver/holder. | 475 // Compute check type based on receiver/holder. |
| 487 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; | 476 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; |
| 488 if (object->IsString()) { | 477 if (object->IsString()) { |
| 489 check = StubCompiler::STRING_CHECK; | 478 check = StubCompiler::STRING_CHECK; |
| 490 } else if (object->IsNumber()) { | 479 } else if (object->IsNumber()) { |
| 491 check = StubCompiler::NUMBER_CHECK; | 480 check = StubCompiler::NUMBER_CHECK; |
| 492 } else if (object->IsBoolean()) { | 481 } else if (object->IsBoolean()) { |
| 493 check = StubCompiler::BOOLEAN_CHECK; | 482 check = StubCompiler::BOOLEAN_CHECK; |
| 494 } | 483 } |
| 495 | 484 |
| 496 Code::Flags flags = | 485 Code::Flags flags = |
| 497 Code::ComputeMonomorphicFlags(kind, | 486 Code::ComputeMonomorphicFlags(kind, |
| 498 CONSTANT_FUNCTION, | 487 CONSTANT_FUNCTION, |
| 499 cache_holder, | 488 cache_holder, |
| 500 in_loop, | 489 in_loop, |
| 501 argc); | 490 argc); |
| 502 Object* code = map->FindInCodeCache(name, flags); | 491 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 503 if (code->IsUndefined()) { | 492 if (code->IsUndefined()) { |
| 504 // If the function hasn't been compiled yet, we cannot do it now | 493 // If the function hasn't been compiled yet, we cannot do it now |
| 505 // because it may cause GC. To avoid this issue, we return an | 494 // because it may cause GC. To avoid this issue, we return an |
| 506 // internal error which will make sure we do not update any | 495 // internal error which will make sure we do not update any |
| 507 // caches. | 496 // caches. |
| 508 if (!function->is_compiled()) return Failure::InternalError(); | 497 if (!function->is_compiled()) return Failure::InternalError(); |
| 509 // Compile the stub - only create stubs for fully compiled functions. | 498 // Compile the stub - only create stubs for fully compiled functions. |
| 510 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 499 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
| 511 code = compiler.CompileCallConstant(object, holder, function, name, check); | 500 code = compiler.CompileCallConstant(object, holder, function, name, check); |
| 512 if (code->IsFailure()) return code; | 501 if (code->IsFailure()) return code; |
| 513 ASSERT_EQ(flags, Code::cast(code)->flags()); | 502 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 514 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 503 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 515 Code::cast(code), name)); | 504 Code::cast(code), name)); |
| 516 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 505 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| 517 if (result->IsFailure()) return result; | 506 if (result->IsFailure()) return result; |
| 518 } | 507 } |
| 519 return code; | 508 return code; |
| 520 } | 509 } |
| 521 | 510 |
| 522 | 511 |
| 523 Object* StubCache::ComputeCallField(int argc, | 512 Object* StubCache::ComputeCallField(int argc, |
| 524 InLoopFlag in_loop, | 513 InLoopFlag in_loop, |
| 525 Code::Kind kind, | 514 Code::Kind kind, |
| 526 String* name, | 515 String* name, |
| 527 Object* object, | 516 Object* object, |
| 528 JSObject* holder, | 517 JSObject* holder, |
| 529 int index) { | 518 int index) { |
| 530 // Compute the check type and the map. | 519 // Compute the check type and the map. |
| 531 InlineCacheHolderFlag cache_holder = | 520 InlineCacheHolderFlag cache_holder = |
| 532 IC::GetCodeCacheForObject(object, holder); | 521 IC::GetCodeCacheForObject(object, holder); |
| 533 Map* map = IC::GetCodeCacheMap(object, cache_holder); | 522 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
| 534 | 523 |
| 535 // TODO(1233596): We cannot do receiver map check for non-JS objects | 524 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| 536 // because they may be represented as immediates without a | 525 // because they may be represented as immediates without a |
| 537 // map. Instead, we check against the map in the holder. | 526 // map. Instead, we check against the map in the holder. |
| 538 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 527 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
| 539 object = holder; | 528 object = holder; |
| 540 } | 529 } |
| 541 | 530 |
| 542 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 531 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
| 543 FIELD, | 532 FIELD, |
| 544 cache_holder, | 533 cache_holder, |
| 545 in_loop, | 534 in_loop, |
| 546 argc); | 535 argc); |
| 547 Object* code = map->FindInCodeCache(name, flags); | 536 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 548 if (code->IsUndefined()) { | 537 if (code->IsUndefined()) { |
| 549 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 538 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
| 550 code = compiler.CompileCallField(JSObject::cast(object), | 539 code = compiler.CompileCallField(JSObject::cast(object), |
| 551 holder, | 540 holder, |
| 552 index, | 541 index, |
| 553 name); | 542 name); |
| 554 if (code->IsFailure()) return code; | 543 if (code->IsFailure()) return code; |
| 555 ASSERT_EQ(flags, Code::cast(code)->flags()); | 544 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 556 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 545 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 557 Code::cast(code), name)); | 546 Code::cast(code), name)); |
| 558 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 547 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| 559 if (result->IsFailure()) return result; | 548 if (result->IsFailure()) return result; |
| 560 } | 549 } |
| 561 return code; | 550 return code; |
| 562 } | 551 } |
| 563 | 552 |
| 564 | 553 |
| 565 Object* StubCache::ComputeCallInterceptor(int argc, | 554 Object* StubCache::ComputeCallInterceptor(int argc, |
| 566 Code::Kind kind, | 555 Code::Kind kind, |
| 567 String* name, | 556 String* name, |
| 568 Object* object, | 557 Object* object, |
| 569 JSObject* holder) { | 558 JSObject* holder) { |
| 570 // Compute the check type and the map. | 559 // Compute the check type and the map. |
| 571 InlineCacheHolderFlag cache_holder = | 560 InlineCacheHolderFlag cache_holder = |
| 572 IC::GetCodeCacheForObject(object, holder); | 561 IC::GetCodeCacheForObject(object, holder); |
| 573 Map* map = IC::GetCodeCacheMap(object, cache_holder); | 562 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
| 574 | 563 |
| 575 // TODO(1233596): We cannot do receiver map check for non-JS objects | 564 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| 576 // because they may be represented as immediates without a | 565 // because they may be represented as immediates without a |
| 577 // map. Instead, we check against the map in the holder. | 566 // map. Instead, we check against the map in the holder. |
| 578 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 567 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
| 579 object = holder; | 568 object = holder; |
| 580 } | 569 } |
| 581 | 570 |
| 582 Code::Flags flags = | 571 Code::Flags flags = |
| 583 Code::ComputeMonomorphicFlags(kind, | 572 Code::ComputeMonomorphicFlags(kind, |
| 584 INTERCEPTOR, | 573 INTERCEPTOR, |
| 585 cache_holder, | 574 cache_holder, |
| 586 NOT_IN_LOOP, | 575 NOT_IN_LOOP, |
| 587 argc); | 576 argc); |
| 588 Object* code = map->FindInCodeCache(name, flags); | 577 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 589 if (code->IsUndefined()) { | 578 if (code->IsUndefined()) { |
| 590 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder); | 579 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder); |
| 591 code = compiler.CompileCallInterceptor(JSObject::cast(object), | 580 code = compiler.CompileCallInterceptor(JSObject::cast(object), |
| 592 holder, | 581 holder, |
| 593 name); | 582 name); |
| 594 if (code->IsFailure()) return code; | 583 if (code->IsFailure()) return code; |
| 595 ASSERT_EQ(flags, Code::cast(code)->flags()); | 584 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 596 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 585 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 597 Code::cast(code), name)); | 586 Code::cast(code), name)); |
| 598 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 587 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| 599 if (result->IsFailure()) return result; | 588 if (result->IsFailure()) return result; |
| 600 } | 589 } |
| 601 return code; | 590 return code; |
| 602 } | 591 } |
| 603 | 592 |
| 604 | 593 |
| 605 Object* StubCache::ComputeCallNormal(int argc, | 594 Object* StubCache::ComputeCallNormal(int argc, |
| 606 InLoopFlag in_loop, | 595 InLoopFlag in_loop, |
| 607 Code::Kind kind, | 596 Code::Kind kind, |
| 608 String* name, | 597 String* name, |
| 609 JSObject* receiver) { | 598 JSObject* receiver) { |
| 610 Object* code = ComputeCallNormal(argc, in_loop, kind); | 599 Object* code = ComputeCallNormal(argc, in_loop, kind); |
| 611 if (code->IsFailure()) return code; | 600 if (code->IsFailure()) return code; |
| 612 return code; | 601 return code; |
| 613 } | 602 } |
| 614 | 603 |
| 615 | 604 |
| 616 Object* StubCache::ComputeCallGlobal(int argc, | 605 Object* StubCache::ComputeCallGlobal(int argc, |
| 617 InLoopFlag in_loop, | 606 InLoopFlag in_loop, |
| 618 Code::Kind kind, | 607 Code::Kind kind, |
| 619 String* name, | 608 String* name, |
| 620 JSObject* receiver, | 609 JSObject* receiver, |
| 621 GlobalObject* holder, | 610 GlobalObject* holder, |
| 622 JSGlobalPropertyCell* cell, | 611 JSGlobalPropertyCell* cell, |
| 623 JSFunction* function) { | 612 JSFunction* function) { |
| 624 InlineCacheHolderFlag cache_holder = | 613 InlineCacheHolderFlag cache_holder = |
| 625 IC::GetCodeCacheForObject(receiver, holder); | 614 IC::GetCodeCacheForObject(receiver, holder); |
| 626 Map* map = IC::GetCodeCacheMap(receiver, cache_holder); | 615 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); |
| 627 Code::Flags flags = | 616 Code::Flags flags = |
| 628 Code::ComputeMonomorphicFlags(kind, | 617 Code::ComputeMonomorphicFlags(kind, |
| 629 NORMAL, | 618 NORMAL, |
| 630 cache_holder, | 619 cache_holder, |
| 631 in_loop, | 620 in_loop, |
| 632 argc); | 621 argc); |
| 633 Object* code = map->FindInCodeCache(name, flags); | 622 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 634 if (code->IsUndefined()) { | 623 if (code->IsUndefined()) { |
| 635 // If the function hasn't been compiled yet, we cannot do it now | 624 // If the function hasn't been compiled yet, we cannot do it now |
| 636 // because it may cause GC. To avoid this issue, we return an | 625 // because it may cause GC. To avoid this issue, we return an |
| 637 // internal error which will make sure we do not update any | 626 // internal error which will make sure we do not update any |
| 638 // caches. | 627 // caches. |
| 639 if (!function->is_compiled()) return Failure::InternalError(); | 628 if (!function->is_compiled()) return Failure::InternalError(); |
| 640 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 629 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
| 641 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 630 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); |
| 642 if (code->IsFailure()) return code; | 631 if (code->IsFailure()) return code; |
| 643 ASSERT_EQ(flags, Code::cast(code)->flags()); | 632 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 644 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 633 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 645 Code::cast(code), name)); | 634 Code::cast(code), name)); |
| 646 Object* result = map->UpdateCodeCache(name, Code::cast(code)); | 635 Object* result = map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| 647 if (result->IsFailure()) return result; | 636 if (result->IsFailure()) return result; |
| 648 } | 637 } |
| 649 return code; | 638 return code; |
| 650 } | 639 } |
| 651 | 640 |
| 652 | 641 |
| 653 static Object* GetProbeValue(Code::Flags flags) { | 642 static Object* GetProbeValue(Code::Flags flags) { |
| 654 // Use raw_unchecked... so we don't get assert failures during GC. | 643 // Use raw_unchecked... so we don't get assert failures during GC. |
| 655 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache(); | 644 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache(); |
| 656 int entry = dictionary->FindEntry(flags); | 645 int entry = dictionary->FindEntry(flags); |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 expected_receiver_type_ = | 1335 expected_receiver_type_ = |
| 1347 FunctionTemplateInfo::cast(signature->receiver()); | 1336 FunctionTemplateInfo::cast(signature->receiver()); |
| 1348 } | 1337 } |
| 1349 } | 1338 } |
| 1350 | 1339 |
| 1351 is_simple_api_call_ = true; | 1340 is_simple_api_call_ = true; |
| 1352 } | 1341 } |
| 1353 | 1342 |
| 1354 | 1343 |
| 1355 } } // namespace v8::internal | 1344 } } // namespace v8::internal |
| OLD | NEW |