OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 return NULL; | 162 return NULL; |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 | 166 |
167 void CodeStub::PrintName(StringStream* stream) { | 167 void CodeStub::PrintName(StringStream* stream) { |
168 stream->Add("%s", MajorName(MajorKey(), false)); | 168 stream->Add("%s", MajorName(MajorKey(), false)); |
169 } | 169 } |
170 | 170 |
171 | 171 |
| 172 void BinaryOpStub::Generate(MacroAssembler* masm) { |
| 173 // Explicitly allow generation of nested stubs. It is safe here because |
| 174 // generation code does not use any raw pointers. |
| 175 AllowStubCallsScope allow_stub_calls(masm, true); |
| 176 |
| 177 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_); |
| 178 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) { |
| 179 // The OddballStub handles a number and an oddball, not two oddballs. |
| 180 operands_type = BinaryOpIC::GENERIC; |
| 181 } |
| 182 switch (operands_type) { |
| 183 case BinaryOpIC::UNINITIALIZED: |
| 184 GenerateTypeTransition(masm); |
| 185 break; |
| 186 case BinaryOpIC::SMI: |
| 187 GenerateSmiStub(masm); |
| 188 break; |
| 189 case BinaryOpIC::INT32: |
| 190 GenerateInt32Stub(masm); |
| 191 break; |
| 192 case BinaryOpIC::HEAP_NUMBER: |
| 193 GenerateHeapNumberStub(masm); |
| 194 break; |
| 195 case BinaryOpIC::ODDBALL: |
| 196 GenerateOddballStub(masm); |
| 197 break; |
| 198 case BinaryOpIC::STRING: |
| 199 GenerateStringStub(masm); |
| 200 break; |
| 201 case BinaryOpIC::GENERIC: |
| 202 GenerateGeneric(masm); |
| 203 break; |
| 204 default: |
| 205 UNREACHABLE(); |
| 206 } |
| 207 } |
| 208 |
| 209 |
| 210 #define __ ACCESS_MASM(masm) |
| 211 |
| 212 |
| 213 void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { |
| 214 switch (op_) { |
| 215 case Token::ADD: |
| 216 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
| 217 break; |
| 218 case Token::SUB: |
| 219 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
| 220 break; |
| 221 case Token::MUL: |
| 222 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
| 223 break; |
| 224 case Token::DIV: |
| 225 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
| 226 break; |
| 227 case Token::MOD: |
| 228 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
| 229 break; |
| 230 case Token::BIT_OR: |
| 231 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |
| 232 break; |
| 233 case Token::BIT_AND: |
| 234 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); |
| 235 break; |
| 236 case Token::BIT_XOR: |
| 237 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); |
| 238 break; |
| 239 case Token::SAR: |
| 240 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION); |
| 241 break; |
| 242 case Token::SHR: |
| 243 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); |
| 244 break; |
| 245 case Token::SHL: |
| 246 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION); |
| 247 break; |
| 248 default: |
| 249 UNREACHABLE(); |
| 250 } |
| 251 } |
| 252 |
| 253 |
| 254 #undef __ |
| 255 |
| 256 |
| 257 void BinaryOpStub::PrintName(StringStream* stream) { |
| 258 const char* op_name = Token::Name(op_); |
| 259 const char* overwrite_name; |
| 260 switch (mode_) { |
| 261 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 262 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
| 263 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
| 264 default: overwrite_name = "UnknownOverwrite"; break; |
| 265 } |
| 266 stream->Add("BinaryOpStub_%s_%s_%s+%s", |
| 267 op_name, |
| 268 overwrite_name, |
| 269 BinaryOpIC::GetName(left_type_), |
| 270 BinaryOpIC::GetName(right_type_)); |
| 271 } |
| 272 |
| 273 |
| 274 void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
| 275 ASSERT(left_type_ == BinaryOpIC::STRING || right_type_ == BinaryOpIC::STRING); |
| 276 ASSERT(op_ == Token::ADD); |
| 277 if (left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING) { |
| 278 GenerateBothStringStub(masm); |
| 279 return; |
| 280 } |
| 281 // Try to add arguments as strings, otherwise, transition to the generic |
| 282 // BinaryOpIC type. |
| 283 GenerateAddStrings(masm); |
| 284 GenerateTypeTransition(masm); |
| 285 } |
| 286 |
| 287 |
172 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { | 288 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { |
173 ASSERT(*known_map_ != NULL); | 289 ASSERT(*known_map_ != NULL); |
174 Isolate* isolate = new_object->GetIsolate(); | 290 Isolate* isolate = new_object->GetIsolate(); |
175 Factory* factory = isolate->factory(); | 291 Factory* factory = isolate->factory(); |
176 return Map::UpdateCodeCache(known_map_, | 292 return Map::UpdateCodeCache(known_map_, |
177 strict() ? | 293 strict() ? |
178 factory->strict_compare_ic_symbol() : | 294 factory->strict_compare_ic_symbol() : |
179 factory->compare_ic_symbol(), | 295 factory->compare_ic_symbol(), |
180 new_object); | 296 new_object); |
181 } | 297 } |
182 | 298 |
183 | 299 |
184 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { | 300 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { |
185 Isolate* isolate = known_map_->GetIsolate(); | 301 Isolate* isolate = known_map_->GetIsolate(); |
186 Factory* factory = isolate->factory(); | 302 Factory* factory = isolate->factory(); |
187 Code::Flags flags = Code::ComputeFlags( | 303 Code::Flags flags = Code::ComputeFlags( |
188 static_cast<Code::Kind>(GetCodeKind()), | 304 static_cast<Code::Kind>(GetCodeKind()), |
189 UNINITIALIZED); | 305 UNINITIALIZED); |
190 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); | 306 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); |
191 Handle<Object> probe( | 307 Handle<Object> probe( |
192 known_map_->FindInCodeCache( | 308 known_map_->FindInCodeCache( |
193 strict() ? | 309 strict() ? |
194 *factory->strict_compare_ic_symbol() : | 310 *factory->strict_compare_ic_symbol() : |
195 *factory->compare_ic_symbol(), | 311 *factory->compare_ic_symbol(), |
196 flags)); | 312 flags)); |
197 if (probe->IsCode()) { | 313 if (probe->IsCode()) { |
198 *code_out = Code::cast(*probe); | 314 *code_out = Code::cast(*probe); |
199 ASSERT(op_ == (*code_out)->compare_operation() + Token::EQ); | 315 #ifdef DEBUG |
| 316 Token::Value cached_op; |
| 317 ICCompareStub::DecodeMinorKey((*code_out)->stub_info(), NULL, NULL, NULL, |
| 318 &cached_op); |
| 319 ASSERT(op_ == cached_op); |
| 320 #endif |
200 return true; | 321 return true; |
201 } | 322 } |
202 return false; | 323 return false; |
203 } | 324 } |
204 | 325 |
205 | 326 |
206 int ICCompareStub::MinorKey() { | 327 int ICCompareStub::MinorKey() { |
207 return OpField::encode(op_ - Token::EQ) | StateField::encode(state_); | 328 return OpField::encode(op_ - Token::EQ) | |
| 329 LeftStateField::encode(left_) | |
| 330 RightStateField::encode(right_) | |
| 331 HandlerStateField::encode(state_); |
208 } | 332 } |
209 | 333 |
210 | 334 |
| 335 void ICCompareStub::DecodeMinorKey(int minor_key, |
| 336 CompareIC::State* left_state, |
| 337 CompareIC::State* right_state, |
| 338 CompareIC::State* handler_state, |
| 339 Token::Value* op) { |
| 340 if (left_state) { |
| 341 *left_state = |
| 342 static_cast<CompareIC::State>(LeftStateField::decode(minor_key)); |
| 343 } |
| 344 if (right_state) { |
| 345 *right_state = |
| 346 static_cast<CompareIC::State>(RightStateField::decode(minor_key)); |
| 347 } |
| 348 if (handler_state) { |
| 349 *handler_state = |
| 350 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key)); |
| 351 } |
| 352 if (op) { |
| 353 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ); |
| 354 } |
| 355 } |
| 356 |
| 357 |
211 void ICCompareStub::Generate(MacroAssembler* masm) { | 358 void ICCompareStub::Generate(MacroAssembler* masm) { |
212 switch (state_) { | 359 switch (state_) { |
213 case CompareIC::UNINITIALIZED: | 360 case CompareIC::UNINITIALIZED: |
214 GenerateMiss(masm); | 361 GenerateMiss(masm); |
215 break; | 362 break; |
216 case CompareIC::SMIS: | 363 case CompareIC::SMI: |
217 GenerateSmis(masm); | 364 GenerateSmis(masm); |
218 break; | 365 break; |
219 case CompareIC::HEAP_NUMBERS: | 366 case CompareIC::HEAP_NUMBER: |
220 GenerateHeapNumbers(masm); | 367 GenerateHeapNumbers(masm); |
221 break; | 368 break; |
222 case CompareIC::STRINGS: | 369 case CompareIC::STRING: |
223 GenerateStrings(masm); | 370 GenerateStrings(masm); |
224 break; | 371 break; |
225 case CompareIC::SYMBOLS: | 372 case CompareIC::SYMBOL: |
226 GenerateSymbols(masm); | 373 GenerateSymbols(masm); |
227 break; | 374 break; |
228 case CompareIC::OBJECTS: | 375 case CompareIC::OBJECT: |
229 GenerateObjects(masm); | 376 GenerateObjects(masm); |
230 break; | 377 break; |
231 case CompareIC::KNOWN_OBJECTS: | 378 case CompareIC::KNOWN_OBJECTS: |
232 ASSERT(*known_map_ != NULL); | 379 ASSERT(*known_map_ != NULL); |
233 GenerateKnownObjects(masm); | 380 GenerateKnownObjects(masm); |
234 break; | 381 break; |
235 default: | 382 case CompareIC::GENERIC: |
236 UNREACHABLE(); | 383 GenerateGeneric(masm); |
| 384 break; |
237 } | 385 } |
238 } | 386 } |
239 | 387 |
240 | 388 |
241 void InstanceofStub::PrintName(StringStream* stream) { | 389 void InstanceofStub::PrintName(StringStream* stream) { |
242 const char* args = ""; | 390 const char* args = ""; |
243 if (HasArgsInRegisters()) { | 391 if (HasArgsInRegisters()) { |
244 args = "_REGS"; | 392 args = "_REGS"; |
245 } | 393 } |
246 | 394 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 // already active, as the hooks won't stack. | 644 // already active, as the hooks won't stack. |
497 if (entry_hook != 0 && entry_hook_ != 0) | 645 if (entry_hook != 0 && entry_hook_ != 0) |
498 return false; | 646 return false; |
499 | 647 |
500 entry_hook_ = entry_hook; | 648 entry_hook_ = entry_hook; |
501 return true; | 649 return true; |
502 } | 650 } |
503 | 651 |
504 | 652 |
505 } } // namespace v8::internal | 653 } } // namespace v8::internal |
OLD | NEW |