| 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 void InterfaceDescriptor::Initialize( | 33 void InterfaceDescriptor::Initialize( |
| 34 int register_parameter_count, | 34 int register_parameter_count, |
| 35 Register* registers, | 35 Register* registers, |
| 36 Representation* register_param_representations, | 36 Representation* register_param_representations, |
| 37 PlatformInterfaceDescriptor* platform_descriptor) { | 37 PlatformInterfaceDescriptor* platform_descriptor) { |
| 38 platform_specific_descriptor_ = platform_descriptor; | 38 platform_specific_descriptor_ = platform_descriptor; |
| 39 register_param_count_ = register_parameter_count; | 39 register_param_count_ = register_parameter_count; |
| 40 | 40 |
| 41 // An interface descriptor must have a context register. | 41 // An interface descriptor must have a context register. |
| 42 ASSERT(register_parameter_count > 0 && registers[0].is(ContextRegister())); | 42 DCHECK(register_parameter_count > 0 && registers[0].is(ContextRegister())); |
| 43 | 43 |
| 44 // InterfaceDescriptor owns a copy of the registers array. | 44 // InterfaceDescriptor owns a copy of the registers array. |
| 45 register_params_.Reset(NewArray<Register>(register_parameter_count)); | 45 register_params_.Reset(NewArray<Register>(register_parameter_count)); |
| 46 for (int i = 0; i < register_parameter_count; i++) { | 46 for (int i = 0; i < register_parameter_count; i++) { |
| 47 register_params_[i] = registers[i]; | 47 register_params_[i] = registers[i]; |
| 48 } | 48 } |
| 49 | 49 |
| 50 // If a representations array is specified, then the descriptor owns that as | 50 // If a representations array is specified, then the descriptor owns that as |
| 51 // well. | 51 // well. |
| 52 if (register_param_representations != NULL) { | 52 if (register_param_representations != NULL) { |
| 53 register_param_representations_.Reset( | 53 register_param_representations_.Reset( |
| 54 NewArray<Representation>(register_parameter_count)); | 54 NewArray<Representation>(register_parameter_count)); |
| 55 for (int i = 0; i < register_parameter_count; i++) { | 55 for (int i = 0; i < register_parameter_count; i++) { |
| 56 // If there is a context register, the representation must be tagged. | 56 // If there is a context register, the representation must be tagged. |
| 57 ASSERT(i != 0 || register_param_representations[i].Equals( | 57 DCHECK(i != 0 || register_param_representations[i].Equals( |
| 58 Representation::Tagged())); | 58 Representation::Tagged())); |
| 59 register_param_representations_[i] = register_param_representations[i]; | 59 register_param_representations_[i] = register_param_representations[i]; |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 void CodeStubInterfaceDescriptor::Initialize( | 65 void CodeStubInterfaceDescriptor::Initialize( |
| 66 CodeStub::Major major, int register_parameter_count, Register* registers, | 66 CodeStub::Major major, int register_parameter_count, Register* registers, |
| 67 Address deoptimization_handler, | 67 Address deoptimization_handler, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 return new_object; | 171 return new_object; |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 Handle<Code> CodeStub::GetCode() { | 175 Handle<Code> CodeStub::GetCode() { |
| 176 Heap* heap = isolate()->heap(); | 176 Heap* heap = isolate()->heap(); |
| 177 Code* code; | 177 Code* code; |
| 178 if (UseSpecialCache() | 178 if (UseSpecialCache() |
| 179 ? FindCodeInSpecialCache(&code) | 179 ? FindCodeInSpecialCache(&code) |
| 180 : FindCodeInCache(&code)) { | 180 : FindCodeInCache(&code)) { |
| 181 ASSERT(GetCodeKind() == code->kind()); | 181 DCHECK(GetCodeKind() == code->kind()); |
| 182 return Handle<Code>(code); | 182 return Handle<Code>(code); |
| 183 } | 183 } |
| 184 | 184 |
| 185 { | 185 { |
| 186 HandleScope scope(isolate()); | 186 HandleScope scope(isolate()); |
| 187 | 187 |
| 188 Handle<Code> new_object = GenerateCode(); | 188 Handle<Code> new_object = GenerateCode(); |
| 189 new_object->set_stub_key(GetKey()); | 189 new_object->set_stub_key(GetKey()); |
| 190 FinishCode(new_object); | 190 FinishCode(new_object); |
| 191 RecordCodeGeneration(new_object); | 191 RecordCodeGeneration(new_object); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 209 UnseededNumberDictionary::AtNumberPut( | 209 UnseededNumberDictionary::AtNumberPut( |
| 210 Handle<UnseededNumberDictionary>(heap->code_stubs()), | 210 Handle<UnseededNumberDictionary>(heap->code_stubs()), |
| 211 GetKey(), | 211 GetKey(), |
| 212 new_object); | 212 new_object); |
| 213 heap->public_set_code_stubs(*dict); | 213 heap->public_set_code_stubs(*dict); |
| 214 } | 214 } |
| 215 code = *new_object; | 215 code = *new_object; |
| 216 } | 216 } |
| 217 | 217 |
| 218 Activate(code); | 218 Activate(code); |
| 219 ASSERT(!NeedsImmovableCode() || | 219 DCHECK(!NeedsImmovableCode() || |
| 220 heap->lo_space()->Contains(code) || | 220 heap->lo_space()->Contains(code) || |
| 221 heap->code_space()->FirstPage()->Contains(code->address())); | 221 heap->code_space()->FirstPage()->Contains(code->address())); |
| 222 return Handle<Code>(code, isolate()); | 222 return Handle<Code>(code, isolate()); |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 const char* CodeStub::MajorName(CodeStub::Major major_key, | 226 const char* CodeStub::MajorName(CodeStub::Major major_key, |
| 227 bool allow_unknown_keys) { | 227 bool allow_unknown_keys) { |
| 228 switch (major_key) { | 228 switch (major_key) { |
| 229 #define DEF_CASE(name) case name: return #name "Stub"; | 229 #define DEF_CASE(name) case name: return #name "Stub"; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 return MONOMORPHIC; | 335 return MONOMORPHIC; |
| 336 case CompareIC::GENERIC: | 336 case CompareIC::GENERIC: |
| 337 return ::v8::internal::GENERIC; | 337 return ::v8::internal::GENERIC; |
| 338 } | 338 } |
| 339 UNREACHABLE(); | 339 UNREACHABLE(); |
| 340 return ::v8::internal::UNINITIALIZED; | 340 return ::v8::internal::UNINITIALIZED; |
| 341 } | 341 } |
| 342 | 342 |
| 343 | 343 |
| 344 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { | 344 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { |
| 345 ASSERT(*known_map_ != NULL); | 345 DCHECK(*known_map_ != NULL); |
| 346 Isolate* isolate = new_object->GetIsolate(); | 346 Isolate* isolate = new_object->GetIsolate(); |
| 347 Factory* factory = isolate->factory(); | 347 Factory* factory = isolate->factory(); |
| 348 return Map::UpdateCodeCache(known_map_, | 348 return Map::UpdateCodeCache(known_map_, |
| 349 strict() ? | 349 strict() ? |
| 350 factory->strict_compare_ic_string() : | 350 factory->strict_compare_ic_string() : |
| 351 factory->compare_ic_string(), | 351 factory->compare_ic_string(), |
| 352 new_object); | 352 new_object); |
| 353 } | 353 } |
| 354 | 354 |
| 355 | 355 |
| 356 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { | 356 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { |
| 357 Factory* factory = isolate()->factory(); | 357 Factory* factory = isolate()->factory(); |
| 358 Code::Flags flags = Code::ComputeFlags( | 358 Code::Flags flags = Code::ComputeFlags( |
| 359 GetCodeKind(), | 359 GetCodeKind(), |
| 360 UNINITIALIZED); | 360 UNINITIALIZED); |
| 361 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); | 361 DCHECK(op_ == Token::EQ || op_ == Token::EQ_STRICT); |
| 362 Handle<Object> probe( | 362 Handle<Object> probe( |
| 363 known_map_->FindInCodeCache( | 363 known_map_->FindInCodeCache( |
| 364 strict() ? | 364 strict() ? |
| 365 *factory->strict_compare_ic_string() : | 365 *factory->strict_compare_ic_string() : |
| 366 *factory->compare_ic_string(), | 366 *factory->compare_ic_string(), |
| 367 flags), | 367 flags), |
| 368 isolate()); | 368 isolate()); |
| 369 if (probe->IsCode()) { | 369 if (probe->IsCode()) { |
| 370 *code_out = Code::cast(*probe); | 370 *code_out = Code::cast(*probe); |
| 371 #ifdef DEBUG | 371 #ifdef DEBUG |
| 372 Token::Value cached_op; | 372 Token::Value cached_op; |
| 373 ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL, | 373 ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL, |
| 374 &cached_op); | 374 &cached_op); |
| 375 ASSERT(op_ == cached_op); | 375 DCHECK(op_ == cached_op); |
| 376 #endif | 376 #endif |
| 377 return true; | 377 return true; |
| 378 } | 378 } |
| 379 return false; | 379 return false; |
| 380 } | 380 } |
| 381 | 381 |
| 382 | 382 |
| 383 int ICCompareStub::MinorKey() const { | 383 int ICCompareStub::MinorKey() const { |
| 384 return OpField::encode(op_ - Token::EQ) | | 384 return OpField::encode(op_ - Token::EQ) | |
| 385 LeftStateField::encode(left_) | | 385 LeftStateField::encode(left_) | |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 case CompareIC::INTERNALIZED_STRING: | 428 case CompareIC::INTERNALIZED_STRING: |
| 429 GenerateInternalizedStrings(masm); | 429 GenerateInternalizedStrings(masm); |
| 430 break; | 430 break; |
| 431 case CompareIC::UNIQUE_NAME: | 431 case CompareIC::UNIQUE_NAME: |
| 432 GenerateUniqueNames(masm); | 432 GenerateUniqueNames(masm); |
| 433 break; | 433 break; |
| 434 case CompareIC::OBJECT: | 434 case CompareIC::OBJECT: |
| 435 GenerateObjects(masm); | 435 GenerateObjects(masm); |
| 436 break; | 436 break; |
| 437 case CompareIC::KNOWN_OBJECT: | 437 case CompareIC::KNOWN_OBJECT: |
| 438 ASSERT(*known_map_ != NULL); | 438 DCHECK(*known_map_ != NULL); |
| 439 GenerateKnownObjects(masm); | 439 GenerateKnownObjects(masm); |
| 440 break; | 440 break; |
| 441 case CompareIC::GENERIC: | 441 case CompareIC::GENERIC: |
| 442 GenerateGeneric(masm); | 442 GenerateGeneric(masm); |
| 443 break; | 443 break; |
| 444 } | 444 } |
| 445 } | 445 } |
| 446 | 446 |
| 447 | 447 |
| 448 void CompareNilICStub::UpdateStatus(Handle<Object> object) { | 448 void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
| 449 ASSERT(!state_.Contains(GENERIC)); | 449 DCHECK(!state_.Contains(GENERIC)); |
| 450 State old_state(state_); | 450 State old_state(state_); |
| 451 if (object->IsNull()) { | 451 if (object->IsNull()) { |
| 452 state_.Add(NULL_TYPE); | 452 state_.Add(NULL_TYPE); |
| 453 } else if (object->IsUndefined()) { | 453 } else if (object->IsUndefined()) { |
| 454 state_.Add(UNDEFINED); | 454 state_.Add(UNDEFINED); |
| 455 } else if (object->IsUndetectableObject() || | 455 } else if (object->IsUndetectableObject() || |
| 456 object->IsOddball() || | 456 object->IsOddball() || |
| 457 !object->IsHeapObject()) { | 457 !object->IsHeapObject()) { |
| 458 state_.RemoveAll(); | 458 state_.RemoveAll(); |
| 459 state_.Add(GENERIC); | 459 state_.Add(GENERIC); |
| 460 } else if (IsMonomorphic()) { | 460 } else if (IsMonomorphic()) { |
| 461 state_.RemoveAll(); | 461 state_.RemoveAll(); |
| 462 state_.Add(GENERIC); | 462 state_.Add(GENERIC); |
| 463 } else { | 463 } else { |
| 464 state_.Add(MONOMORPHIC_MAP); | 464 state_.Add(MONOMORPHIC_MAP); |
| 465 } | 465 } |
| 466 TraceTransition(old_state, state_); | 466 TraceTransition(old_state, state_); |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 template<class StateType> | 470 template<class StateType> |
| 471 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { | 471 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
| 472 // Note: Although a no-op transition is semantically OK, it is hinting at a | 472 // Note: Although a no-op transition is semantically OK, it is hinting at a |
| 473 // bug somewhere in our state transition machinery. | 473 // bug somewhere in our state transition machinery. |
| 474 ASSERT(from != to); | 474 DCHECK(from != to); |
| 475 if (!FLAG_trace_ic) return; | 475 if (!FLAG_trace_ic) return; |
| 476 OFStream os(stdout); | 476 OFStream os(stdout); |
| 477 os << "["; | 477 os << "["; |
| 478 PrintBaseName(os); | 478 PrintBaseName(os); |
| 479 os << ": " << from << "=>" << to << "]" << endl; | 479 os << ": " << from << "=>" << to << "]" << endl; |
| 480 } | 480 } |
| 481 | 481 |
| 482 | 482 |
| 483 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT | 483 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT |
| 484 CodeStub::PrintBaseName(os); | 484 CodeStub::PrintBaseName(os); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 Add(SPEC_OBJECT); | 817 Add(SPEC_OBJECT); |
| 818 return !object->IsUndetectableObject(); | 818 return !object->IsUndetectableObject(); |
| 819 } else if (object->IsString()) { | 819 } else if (object->IsString()) { |
| 820 Add(STRING); | 820 Add(STRING); |
| 821 return !object->IsUndetectableObject() && | 821 return !object->IsUndetectableObject() && |
| 822 String::cast(*object)->length() != 0; | 822 String::cast(*object)->length() != 0; |
| 823 } else if (object->IsSymbol()) { | 823 } else if (object->IsSymbol()) { |
| 824 Add(SYMBOL); | 824 Add(SYMBOL); |
| 825 return true; | 825 return true; |
| 826 } else if (object->IsHeapNumber()) { | 826 } else if (object->IsHeapNumber()) { |
| 827 ASSERT(!object->IsUndetectableObject()); | 827 DCHECK(!object->IsUndetectableObject()); |
| 828 Add(HEAP_NUMBER); | 828 Add(HEAP_NUMBER); |
| 829 double value = HeapNumber::cast(*object)->value(); | 829 double value = HeapNumber::cast(*object)->value(); |
| 830 return value != 0 && !std::isnan(value); | 830 return value != 0 && !std::isnan(value); |
| 831 } else { | 831 } else { |
| 832 // We should never see an internal object at runtime here! | 832 // We should never see an internal object at runtime here! |
| 833 UNREACHABLE(); | 833 UNREACHABLE(); |
| 834 return true; | 834 return true; |
| 835 } | 835 } |
| 836 } | 836 } |
| 837 | 837 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 855 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE); | 855 StubFailureTrampolineStub stub2(isolate, JS_FUNCTION_STUB_MODE); |
| 856 stub1.GetCode(); | 856 stub1.GetCode(); |
| 857 stub2.GetCode(); | 857 stub2.GetCode(); |
| 858 } | 858 } |
| 859 | 859 |
| 860 | 860 |
| 861 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, | 861 void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, |
| 862 intptr_t stack_pointer, | 862 intptr_t stack_pointer, |
| 863 Isolate* isolate) { | 863 Isolate* isolate) { |
| 864 FunctionEntryHook entry_hook = isolate->function_entry_hook(); | 864 FunctionEntryHook entry_hook = isolate->function_entry_hook(); |
| 865 ASSERT(entry_hook != NULL); | 865 DCHECK(entry_hook != NULL); |
| 866 entry_hook(function, stack_pointer); | 866 entry_hook(function, stack_pointer); |
| 867 } | 867 } |
| 868 | 868 |
| 869 | 869 |
| 870 static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) { | 870 static void InstallDescriptor(Isolate* isolate, HydrogenCodeStub* stub) { |
| 871 int major_key = stub->MajorKey(); | 871 int major_key = stub->MajorKey(); |
| 872 CodeStubInterfaceDescriptor* descriptor = | 872 CodeStubInterfaceDescriptor* descriptor = |
| 873 isolate->code_stub_interface_descriptor(major_key); | 873 isolate->code_stub_interface_descriptor(major_key); |
| 874 if (!descriptor->IsInitialized()) { | 874 if (!descriptor->IsInitialized()) { |
| 875 stub->InitializeInterfaceDescriptor(descriptor); | 875 stub->InitializeInterfaceDescriptor(descriptor); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 InstallDescriptor(isolate, &stub3); | 979 InstallDescriptor(isolate, &stub3); |
| 980 } | 980 } |
| 981 | 981 |
| 982 InternalArrayConstructorStub::InternalArrayConstructorStub( | 982 InternalArrayConstructorStub::InternalArrayConstructorStub( |
| 983 Isolate* isolate) : PlatformCodeStub(isolate) { | 983 Isolate* isolate) : PlatformCodeStub(isolate) { |
| 984 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 984 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 985 } | 985 } |
| 986 | 986 |
| 987 | 987 |
| 988 } } // namespace v8::internal | 988 } } // namespace v8::internal |
| OLD | NEW |