| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 stub.GetCode(); | 212 stub.GetCode(); |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 | 215 |
| 216 // Generate special versions of the stub. | 216 // Generate special versions of the stub. |
| 217 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime); | 217 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime); |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT | 221 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT |
| 222 os << state_; | 222 os << state(); |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 // static | 226 // static |
| 227 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate, | 227 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate, |
| 228 const BinaryOpIC::State& state) { | 228 const BinaryOpIC::State& state) { |
| 229 BinaryOpICStub stub(isolate, state); | 229 BinaryOpICStub stub(isolate, state); |
| 230 stub.GetCode(); | 230 stub.GetCode(); |
| 231 } | 231 } |
| 232 | 232 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 263 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { | 263 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { |
| 264 os << "_CheckRight"; | 264 os << "_CheckRight"; |
| 265 } | 265 } |
| 266 if (pretenure_flag() == TENURED) { | 266 if (pretenure_flag() == TENURED) { |
| 267 os << "_Tenured"; | 267 os << "_Tenured"; |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 | 270 |
| 271 | 271 |
| 272 InlineCacheState ICCompareStub::GetICState() const { | 272 InlineCacheState ICCompareStub::GetICState() const { |
| 273 CompareIC::State state = Max(left_, right_); | 273 CompareIC::State state = Max(left(), right()); |
| 274 switch (state) { | 274 switch (state) { |
| 275 case CompareIC::UNINITIALIZED: | 275 case CompareIC::UNINITIALIZED: |
| 276 return ::v8::internal::UNINITIALIZED; | 276 return ::v8::internal::UNINITIALIZED; |
| 277 case CompareIC::SMI: | 277 case CompareIC::SMI: |
| 278 case CompareIC::NUMBER: | 278 case CompareIC::NUMBER: |
| 279 case CompareIC::INTERNALIZED_STRING: | 279 case CompareIC::INTERNALIZED_STRING: |
| 280 case CompareIC::STRING: | 280 case CompareIC::STRING: |
| 281 case CompareIC::UNIQUE_NAME: | 281 case CompareIC::UNIQUE_NAME: |
| 282 case CompareIC::OBJECT: | 282 case CompareIC::OBJECT: |
| 283 case CompareIC::KNOWN_OBJECT: | 283 case CompareIC::KNOWN_OBJECT: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 300 factory->compare_ic_string(), | 300 factory->compare_ic_string(), |
| 301 new_object); | 301 new_object); |
| 302 } | 302 } |
| 303 | 303 |
| 304 | 304 |
| 305 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { | 305 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { |
| 306 Factory* factory = isolate()->factory(); | 306 Factory* factory = isolate()->factory(); |
| 307 Code::Flags flags = Code::ComputeFlags( | 307 Code::Flags flags = Code::ComputeFlags( |
| 308 GetCodeKind(), | 308 GetCodeKind(), |
| 309 UNINITIALIZED); | 309 UNINITIALIZED); |
| 310 DCHECK(op_ == Token::EQ || op_ == Token::EQ_STRICT); | 310 DCHECK(op() == Token::EQ || op() == Token::EQ_STRICT); |
| 311 Handle<Object> probe( | 311 Handle<Object> probe( |
| 312 known_map_->FindInCodeCache( | 312 known_map_->FindInCodeCache( |
| 313 strict() ? | 313 strict() ? |
| 314 *factory->strict_compare_ic_string() : | 314 *factory->strict_compare_ic_string() : |
| 315 *factory->compare_ic_string(), | 315 *factory->compare_ic_string(), |
| 316 flags), | 316 flags), |
| 317 isolate()); | 317 isolate()); |
| 318 if (probe->IsCode()) { | 318 if (probe->IsCode()) { |
| 319 *code_out = Code::cast(*probe); | 319 *code_out = Code::cast(*probe); |
| 320 #ifdef DEBUG | 320 #ifdef DEBUG |
| 321 Token::Value cached_op; | 321 ICCompareStub decode((*code_out)->stub_key()); |
| 322 ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL, | 322 DCHECK(op() == decode.op()); |
| 323 &cached_op); | 323 DCHECK(left() == decode.left()); |
| 324 DCHECK(op_ == cached_op); | 324 DCHECK(right() == decode.right()); |
| 325 DCHECK(state() == decode.state()); |
| 325 #endif | 326 #endif |
| 326 return true; | 327 return true; |
| 327 } | 328 } |
| 328 return false; | 329 return false; |
| 329 } | 330 } |
| 330 | 331 |
| 331 | 332 |
| 332 uint32_t ICCompareStub::MinorKey() const { | |
| 333 return OpField::encode(op_ - Token::EQ) | | |
| 334 LeftStateField::encode(left_) | | |
| 335 RightStateField::encode(right_) | | |
| 336 HandlerStateField::encode(state_); | |
| 337 } | |
| 338 | |
| 339 | |
| 340 void ICCompareStub::DecodeKey(uint32_t stub_key, CompareIC::State* left_state, | |
| 341 CompareIC::State* right_state, | |
| 342 CompareIC::State* handler_state, | |
| 343 Token::Value* op) { | |
| 344 int minor_key = MinorKeyFromKey(stub_key); | |
| 345 if (left_state) { | |
| 346 *left_state = | |
| 347 static_cast<CompareIC::State>(LeftStateField::decode(minor_key)); | |
| 348 } | |
| 349 if (right_state) { | |
| 350 *right_state = | |
| 351 static_cast<CompareIC::State>(RightStateField::decode(minor_key)); | |
| 352 } | |
| 353 if (handler_state) { | |
| 354 *handler_state = | |
| 355 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key)); | |
| 356 } | |
| 357 if (op) { | |
| 358 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 | |
| 363 void ICCompareStub::Generate(MacroAssembler* masm) { | 333 void ICCompareStub::Generate(MacroAssembler* masm) { |
| 364 switch (state_) { | 334 switch (state()) { |
| 365 case CompareIC::UNINITIALIZED: | 335 case CompareIC::UNINITIALIZED: |
| 366 GenerateMiss(masm); | 336 GenerateMiss(masm); |
| 367 break; | 337 break; |
| 368 case CompareIC::SMI: | 338 case CompareIC::SMI: |
| 369 GenerateSmis(masm); | 339 GenerateSmis(masm); |
| 370 break; | 340 break; |
| 371 case CompareIC::NUMBER: | 341 case CompareIC::NUMBER: |
| 372 GenerateNumbers(masm); | 342 GenerateNumbers(masm); |
| 373 break; | 343 break; |
| 374 case CompareIC::STRING: | 344 case CompareIC::STRING: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 388 GenerateKnownObjects(masm); | 358 GenerateKnownObjects(masm); |
| 389 break; | 359 break; |
| 390 case CompareIC::GENERIC: | 360 case CompareIC::GENERIC: |
| 391 GenerateGeneric(masm); | 361 GenerateGeneric(masm); |
| 392 break; | 362 break; |
| 393 } | 363 } |
| 394 } | 364 } |
| 395 | 365 |
| 396 | 366 |
| 397 void CompareNilICStub::UpdateStatus(Handle<Object> object) { | 367 void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
| 398 DCHECK(!state_.Contains(GENERIC)); | 368 State state = this->state(); |
| 399 State old_state(state_); | 369 DCHECK(!state.Contains(GENERIC)); |
| 370 State old_state = state; |
| 400 if (object->IsNull()) { | 371 if (object->IsNull()) { |
| 401 state_.Add(NULL_TYPE); | 372 state.Add(NULL_TYPE); |
| 402 } else if (object->IsUndefined()) { | 373 } else if (object->IsUndefined()) { |
| 403 state_.Add(UNDEFINED); | 374 state.Add(UNDEFINED); |
| 404 } else if (object->IsUndetectableObject() || | 375 } else if (object->IsUndetectableObject() || |
| 405 object->IsOddball() || | 376 object->IsOddball() || |
| 406 !object->IsHeapObject()) { | 377 !object->IsHeapObject()) { |
| 407 state_.RemoveAll(); | 378 state.RemoveAll(); |
| 408 state_.Add(GENERIC); | 379 state.Add(GENERIC); |
| 409 } else if (IsMonomorphic()) { | 380 } else if (IsMonomorphic()) { |
| 410 state_.RemoveAll(); | 381 state.RemoveAll(); |
| 411 state_.Add(GENERIC); | 382 state.Add(GENERIC); |
| 412 } else { | 383 } else { |
| 413 state_.Add(MONOMORPHIC_MAP); | 384 state.Add(MONOMORPHIC_MAP); |
| 414 } | 385 } |
| 415 TraceTransition(old_state, state_); | 386 TraceTransition(old_state, state); |
| 387 set_sub_minor_key(TypesBits::update(sub_minor_key(), state.ToIntegral())); |
| 416 } | 388 } |
| 417 | 389 |
| 418 | 390 |
| 419 template<class StateType> | 391 template<class StateType> |
| 420 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { | 392 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
| 421 // Note: Although a no-op transition is semantically OK, it is hinting at a | 393 // Note: Although a no-op transition is semantically OK, it is hinting at a |
| 422 // bug somewhere in our state transition machinery. | 394 // bug somewhere in our state transition machinery. |
| 423 DCHECK(from != to); | 395 DCHECK(from != to); |
| 424 if (!FLAG_trace_ic) return; | 396 if (!FLAG_trace_ic) return; |
| 425 OFStream os(stdout); | 397 OFStream os(stdout); |
| 426 os << "["; | 398 os << "["; |
| 427 PrintBaseName(os); | 399 PrintBaseName(os); |
| 428 os << ": " << from << "=>" << to << "]" << endl; | 400 os << ": " << from << "=>" << to << "]" << endl; |
| 429 } | 401 } |
| 430 | 402 |
| 431 | 403 |
| 432 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT | 404 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT |
| 433 CodeStub::PrintBaseName(os); | 405 CodeStub::PrintBaseName(os); |
| 434 os << ((nil_value_ == kNullValue) ? "(NullValue)" : "(UndefinedValue)"); | 406 os << ((nil_value() == kNullValue) ? "(NullValue)" : "(UndefinedValue)"); |
| 435 } | 407 } |
| 436 | 408 |
| 437 | 409 |
| 438 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT | 410 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT |
| 439 os << state_; | 411 os << state(); |
| 440 } | 412 } |
| 441 | 413 |
| 442 | 414 |
| 443 // TODO(svenpanne) Make this a real infix_ostream_iterator. | 415 // TODO(svenpanne) Make this a real infix_ostream_iterator. |
| 444 class SimpleListPrinter { | 416 class SimpleListPrinter { |
| 445 public: | 417 public: |
| 446 explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {} | 418 explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {} |
| 447 | 419 |
| 448 void Add(const char* s) { | 420 void Add(const char* s) { |
| 449 if (first_) { | 421 if (first_) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 466 if (s.IsEmpty()) p.Add("None"); | 438 if (s.IsEmpty()) p.Add("None"); |
| 467 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined"); | 439 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined"); |
| 468 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null"); | 440 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null"); |
| 469 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap"); | 441 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap"); |
| 470 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic"); | 442 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic"); |
| 471 return os << ")"; | 443 return os << ")"; |
| 472 } | 444 } |
| 473 | 445 |
| 474 | 446 |
| 475 Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) { | 447 Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) { |
| 476 if (state_.Contains(CompareNilICStub::GENERIC)) { | 448 State state = this->state(); |
| 477 return Type::Any(zone); | 449 if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any(zone); |
| 478 } | |
| 479 | 450 |
| 480 Type* result = Type::None(zone); | 451 Type* result = Type::None(zone); |
| 481 if (state_.Contains(CompareNilICStub::UNDEFINED)) { | 452 if (state.Contains(CompareNilICStub::UNDEFINED)) { |
| 482 result = Type::Union(result, Type::Undefined(zone), zone); | 453 result = Type::Union(result, Type::Undefined(zone), zone); |
| 483 } | 454 } |
| 484 if (state_.Contains(CompareNilICStub::NULL_TYPE)) { | 455 if (state.Contains(CompareNilICStub::NULL_TYPE)) { |
| 485 result = Type::Union(result, Type::Null(zone), zone); | 456 result = Type::Union(result, Type::Null(zone), zone); |
| 486 } | 457 } |
| 487 if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { | 458 if (state.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { |
| 488 Type* type = | 459 Type* type = |
| 489 map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone); | 460 map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone); |
| 490 result = Type::Union(result, type, zone); | 461 result = Type::Union(result, type, zone); |
| 491 } | 462 } |
| 492 | 463 |
| 493 return result; | 464 return result; |
| 494 } | 465 } |
| 495 | 466 |
| 496 | 467 |
| 497 Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) { | 468 Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) { |
| 498 Type* output_type = GetType(zone, map); | 469 Type* output_type = GetType(zone, map); |
| 499 Type* nil_type = | 470 Type* nil_type = |
| 500 nil_value_ == kNullValue ? Type::Null(zone) : Type::Undefined(zone); | 471 nil_value() == kNullValue ? Type::Null(zone) : Type::Undefined(zone); |
| 501 return Type::Union(output_type, nil_type, zone); | 472 return Type::Union(output_type, nil_type, zone); |
| 502 } | 473 } |
| 503 | 474 |
| 504 | 475 |
| 505 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT | 476 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT |
| 506 os << state() << " (Array)"; | 477 os << state() << " (Array)"; |
| 507 } | 478 } |
| 508 | 479 |
| 509 | 480 |
| 510 void CallICStub::PrintState(OStream& os) const { // NOLINT | 481 void CallICStub::PrintState(OStream& os) const { // NOLINT |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 InstallDescriptor(isolate, &stub3); | 1087 InstallDescriptor(isolate, &stub3); |
| 1117 } | 1088 } |
| 1118 | 1089 |
| 1119 InternalArrayConstructorStub::InternalArrayConstructorStub( | 1090 InternalArrayConstructorStub::InternalArrayConstructorStub( |
| 1120 Isolate* isolate) : PlatformCodeStub(isolate) { | 1091 Isolate* isolate) : PlatformCodeStub(isolate) { |
| 1121 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 1092 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 1122 } | 1093 } |
| 1123 | 1094 |
| 1124 | 1095 |
| 1125 } } // namespace v8::internal | 1096 } } // namespace v8::internal |
| OLD | NEW |