| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 return true; | 45 return true; |
| 46 } | 46 } |
| 47 return false; | 47 return false; |
| 48 } | 48 } |
| 49 | 49 |
| 50 | 50 |
| 51 void CodeStub::GenerateCode(MacroAssembler* masm) { | 51 void CodeStub::GenerateCode(MacroAssembler* masm) { |
| 52 // Update the static counter each time a new code stub is generated. | 52 // Update the static counter each time a new code stub is generated. |
| 53 masm->isolate()->counters()->code_stubs()->Increment(); | 53 masm->isolate()->counters()->code_stubs()->Increment(); |
| 54 | 54 |
| 55 // Nested stubs are not allowed for leafs. | 55 // Nested stubs are not allowed for leaves. |
| 56 AllowStubCallsScope allow_scope(masm, AllowsStubCalls()); | 56 AllowStubCallsScope allow_scope(masm, false); |
| 57 | 57 |
| 58 // Generate the code for the stub. | 58 // Generate the code for the stub. |
| 59 masm->set_generating_stub(true); | 59 masm->set_generating_stub(true); |
| 60 NoCurrentFrameScope scope(masm); |
| 60 Generate(masm); | 61 Generate(masm); |
| 61 } | 62 } |
| 62 | 63 |
| 63 | 64 |
| 64 SmartArrayPointer<const char> CodeStub::GetName() { | 65 SmartArrayPointer<const char> CodeStub::GetName() { |
| 65 char buffer[100]; | 66 char buffer[100]; |
| 66 NoAllocationStringAllocator allocator(buffer, | 67 NoAllocationStringAllocator allocator(buffer, |
| 67 static_cast<unsigned>(sizeof(buffer))); | 68 static_cast<unsigned>(sizeof(buffer))); |
| 68 StringStream stream(&allocator); | 69 StringStream stream(&allocator); |
| 69 PrintName(&stream); | 70 PrintName(&stream); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 RecordCodeGeneration(*new_object, &masm); | 121 RecordCodeGeneration(*new_object, &masm); |
| 121 FinishCode(*new_object); | 122 FinishCode(*new_object); |
| 122 | 123 |
| 123 // Update the dictionary and the root in Heap. | 124 // Update the dictionary and the root in Heap. |
| 124 Handle<NumberDictionary> dict = | 125 Handle<NumberDictionary> dict = |
| 125 factory->DictionaryAtNumberPut( | 126 factory->DictionaryAtNumberPut( |
| 126 Handle<NumberDictionary>(heap->code_stubs()), | 127 Handle<NumberDictionary>(heap->code_stubs()), |
| 127 GetKey(), | 128 GetKey(), |
| 128 new_object); | 129 new_object); |
| 129 heap->public_set_code_stubs(*dict); | 130 heap->public_set_code_stubs(*dict); |
| 130 | |
| 131 code = *new_object; | 131 code = *new_object; |
| 132 Activate(code); |
| 133 } else { |
| 134 CHECK(IsPregenerated() == code->is_pregenerated()); |
| 132 } | 135 } |
| 133 | 136 |
| 134 ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code)); | 137 ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code)); |
| 135 return Handle<Code>(code, isolate); | 138 return Handle<Code>(code, isolate); |
| 136 } | 139 } |
| 137 | 140 |
| 138 | 141 |
| 139 MaybeObject* CodeStub::TryGetCode() { | 142 MaybeObject* CodeStub::TryGetCode() { |
| 140 Code* code; | 143 Code* code; |
| 141 if (!FindCodeInCache(&code)) { | 144 if (!FindCodeInCache(&code)) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 159 } | 162 } |
| 160 code = Code::cast(new_object); | 163 code = Code::cast(new_object); |
| 161 RecordCodeGeneration(code, &masm); | 164 RecordCodeGeneration(code, &masm); |
| 162 FinishCode(code); | 165 FinishCode(code); |
| 163 | 166 |
| 164 // Try to update the code cache but do not fail if unable. | 167 // Try to update the code cache but do not fail if unable. |
| 165 MaybeObject* maybe_new_object = | 168 MaybeObject* maybe_new_object = |
| 166 heap->code_stubs()->AtNumberPut(GetKey(), code); | 169 heap->code_stubs()->AtNumberPut(GetKey(), code); |
| 167 if (maybe_new_object->ToObject(&new_object)) { | 170 if (maybe_new_object->ToObject(&new_object)) { |
| 168 heap->public_set_code_stubs(NumberDictionary::cast(new_object)); | 171 heap->public_set_code_stubs(NumberDictionary::cast(new_object)); |
| 172 } else if (MustBeInStubCache()) { |
| 173 return maybe_new_object; |
| 169 } | 174 } |
| 175 |
| 176 Activate(code); |
| 170 } | 177 } |
| 171 | 178 |
| 172 return code; | 179 return code; |
| 173 } | 180 } |
| 174 | 181 |
| 175 | 182 |
| 176 const char* CodeStub::MajorName(CodeStub::Major major_key, | 183 const char* CodeStub::MajorName(CodeStub::Major major_key, |
| 177 bool allow_unknown_keys) { | 184 bool allow_unknown_keys) { |
| 178 switch (major_key) { | 185 switch (major_key) { |
| 179 #define DEF_CASE(name) case name: return #name "Stub"; | 186 #define DEF_CASE(name) case name: return #name "Stub"; |
| 180 CODE_STUB_LIST(DEF_CASE) | 187 CODE_STUB_LIST(DEF_CASE) |
| 181 #undef DEF_CASE | 188 #undef DEF_CASE |
| 182 default: | 189 default: |
| 183 if (!allow_unknown_keys) { | 190 if (!allow_unknown_keys) { |
| 184 UNREACHABLE(); | 191 UNREACHABLE(); |
| 185 } | 192 } |
| 186 return NULL; | 193 return NULL; |
| 187 } | 194 } |
| 188 } | 195 } |
| 189 | 196 |
| 190 | 197 |
| 198 void CodeStub::PrintName(StringStream* stream) { |
| 199 stream->Add("%s", MajorName(MajorKey(), false)); |
| 200 } |
| 201 |
| 202 |
| 191 int ICCompareStub::MinorKey() { | 203 int ICCompareStub::MinorKey() { |
| 192 return OpField::encode(op_ - Token::EQ) | StateField::encode(state_); | 204 return OpField::encode(op_ - Token::EQ) | StateField::encode(state_); |
| 193 } | 205 } |
| 194 | 206 |
| 195 | 207 |
| 196 void ICCompareStub::Generate(MacroAssembler* masm) { | 208 void ICCompareStub::Generate(MacroAssembler* masm) { |
| 197 switch (state_) { | 209 switch (state_) { |
| 198 case CompareIC::UNINITIALIZED: | 210 case CompareIC::UNINITIALIZED: |
| 199 GenerateMiss(masm); | 211 GenerateMiss(masm); |
| 200 break; | 212 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 stream->Add("InstanceofStub%s%s%s", | 250 stream->Add("InstanceofStub%s%s%s", |
| 239 args, | 251 args, |
| 240 inline_check, | 252 inline_check, |
| 241 return_true_false_object); | 253 return_true_false_object); |
| 242 } | 254 } |
| 243 | 255 |
| 244 | 256 |
| 245 void KeyedLoadElementStub::Generate(MacroAssembler* masm) { | 257 void KeyedLoadElementStub::Generate(MacroAssembler* masm) { |
| 246 switch (elements_kind_) { | 258 switch (elements_kind_) { |
| 247 case FAST_ELEMENTS: | 259 case FAST_ELEMENTS: |
| 260 case FAST_SMI_ONLY_ELEMENTS: |
| 248 KeyedLoadStubCompiler::GenerateLoadFastElement(masm); | 261 KeyedLoadStubCompiler::GenerateLoadFastElement(masm); |
| 249 break; | 262 break; |
| 250 case FAST_DOUBLE_ELEMENTS: | 263 case FAST_DOUBLE_ELEMENTS: |
| 251 KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm); | 264 KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm); |
| 252 break; | 265 break; |
| 253 case EXTERNAL_BYTE_ELEMENTS: | 266 case EXTERNAL_BYTE_ELEMENTS: |
| 254 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 267 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 255 case EXTERNAL_SHORT_ELEMENTS: | 268 case EXTERNAL_SHORT_ELEMENTS: |
| 256 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 269 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 257 case EXTERNAL_INT_ELEMENTS: | 270 case EXTERNAL_INT_ELEMENTS: |
| 258 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 271 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 259 case EXTERNAL_FLOAT_ELEMENTS: | 272 case EXTERNAL_FLOAT_ELEMENTS: |
| 260 case EXTERNAL_DOUBLE_ELEMENTS: | 273 case EXTERNAL_DOUBLE_ELEMENTS: |
| 261 case EXTERNAL_PIXEL_ELEMENTS: | 274 case EXTERNAL_PIXEL_ELEMENTS: |
| 262 KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); | 275 KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); |
| 263 break; | 276 break; |
| 264 case DICTIONARY_ELEMENTS: | 277 case DICTIONARY_ELEMENTS: |
| 265 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); | 278 KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); |
| 266 break; | 279 break; |
| 267 case NON_STRICT_ARGUMENTS_ELEMENTS: | 280 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 268 UNREACHABLE(); | 281 UNREACHABLE(); |
| 269 break; | 282 break; |
| 270 } | 283 } |
| 271 } | 284 } |
| 272 | 285 |
| 273 | 286 |
| 274 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { | 287 void KeyedStoreElementStub::Generate(MacroAssembler* masm) { |
| 275 switch (elements_kind_) { | 288 switch (elements_kind_) { |
| 276 case FAST_ELEMENTS: | 289 case FAST_ELEMENTS: |
| 277 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_); | 290 case FAST_SMI_ONLY_ELEMENTS: { |
| 291 KeyedStoreStubCompiler::GenerateStoreFastElement(masm, |
| 292 is_js_array_, |
| 293 elements_kind_); |
| 294 } |
| 278 break; | 295 break; |
| 279 case FAST_DOUBLE_ELEMENTS: | 296 case FAST_DOUBLE_ELEMENTS: |
| 280 KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm, | 297 KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm, |
| 281 is_js_array_); | 298 is_js_array_); |
| 282 break; | 299 break; |
| 283 case EXTERNAL_BYTE_ELEMENTS: | 300 case EXTERNAL_BYTE_ELEMENTS: |
| 284 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 301 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 285 case EXTERNAL_SHORT_ELEMENTS: | 302 case EXTERNAL_SHORT_ELEMENTS: |
| 286 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 303 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 287 case EXTERNAL_INT_ELEMENTS: | 304 case EXTERNAL_INT_ELEMENTS: |
| 288 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 305 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 289 case EXTERNAL_FLOAT_ELEMENTS: | 306 case EXTERNAL_FLOAT_ELEMENTS: |
| 290 case EXTERNAL_DOUBLE_ELEMENTS: | 307 case EXTERNAL_DOUBLE_ELEMENTS: |
| 291 case EXTERNAL_PIXEL_ELEMENTS: | 308 case EXTERNAL_PIXEL_ELEMENTS: |
| 292 KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_); | 309 KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_); |
| 293 break; | 310 break; |
| 294 case DICTIONARY_ELEMENTS: | 311 case DICTIONARY_ELEMENTS: |
| 295 KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm); | 312 KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm); |
| 296 break; | 313 break; |
| 297 case NON_STRICT_ARGUMENTS_ELEMENTS: | 314 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 298 UNREACHABLE(); | 315 UNREACHABLE(); |
| 299 break; | 316 break; |
| 300 } | 317 } |
| 301 } | 318 } |
| 302 | 319 |
| 303 | 320 |
| 304 void ArgumentsAccessStub::PrintName(StringStream* stream) { | 321 void ArgumentsAccessStub::PrintName(StringStream* stream) { |
| 305 const char* type_name = NULL; // Make g++ happy. | 322 stream->Add("ArgumentsAccessStub_"); |
| 306 switch (type_) { | 323 switch (type_) { |
| 307 case READ_ELEMENT: type_name = "ReadElement"; break; | 324 case READ_ELEMENT: stream->Add("ReadElement"); break; |
| 308 case NEW_NON_STRICT_FAST: type_name = "NewNonStrictFast"; break; | 325 case NEW_NON_STRICT_FAST: stream->Add("NewNonStrictFast"); break; |
| 309 case NEW_NON_STRICT_SLOW: type_name = "NewNonStrictSlow"; break; | 326 case NEW_NON_STRICT_SLOW: stream->Add("NewNonStrictSlow"); break; |
| 310 case NEW_STRICT: type_name = "NewStrict"; break; | 327 case NEW_STRICT: stream->Add("NewStrict"); break; |
| 311 } | 328 } |
| 312 stream->Add("ArgumentsAccessStub_%s", type_name); | |
| 313 } | 329 } |
| 314 | 330 |
| 315 | 331 |
| 316 void CallFunctionStub::PrintName(StringStream* stream) { | 332 void CallFunctionStub::PrintName(StringStream* stream) { |
| 317 const char* flags_name = NULL; // Make g++ happy. | 333 stream->Add("CallFunctionStub_Args%d", argc_); |
| 318 switch (flags_) { | 334 if (ReceiverMightBeImplicit()) stream->Add("_Implicit"); |
| 319 case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break; | 335 if (RecordCallTarget()) stream->Add("_Recording"); |
| 320 case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break; | |
| 321 } | |
| 322 stream->Add("CallFunctionStub_Args%d%s", argc_, flags_name); | |
| 323 } | 336 } |
| 324 | 337 |
| 325 | 338 |
| 326 void ToBooleanStub::PrintName(StringStream* stream) { | 339 void ToBooleanStub::PrintName(StringStream* stream) { |
| 327 stream->Add("ToBooleanStub_"); | 340 stream->Add("ToBooleanStub_"); |
| 328 types_.Print(stream); | 341 types_.Print(stream); |
| 329 } | 342 } |
| 330 | 343 |
| 331 | 344 |
| 332 void ToBooleanStub::Types::Print(StringStream* stream) const { | 345 void ToBooleanStub::Types::Print(StringStream* stream) const { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 } | 409 } |
| 397 | 410 |
| 398 | 411 |
| 399 bool ToBooleanStub::Types::CanBeUndetectable() const { | 412 bool ToBooleanStub::Types::CanBeUndetectable() const { |
| 400 return Contains(ToBooleanStub::SPEC_OBJECT) | 413 return Contains(ToBooleanStub::SPEC_OBJECT) |
| 401 || Contains(ToBooleanStub::STRING); | 414 || Contains(ToBooleanStub::STRING); |
| 402 } | 415 } |
| 403 | 416 |
| 404 | 417 |
| 405 } } // namespace v8::internal | 418 } } // namespace v8::internal |
| OLD | NEW |