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/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/field-index.h" | 9 #include "src/field-index.h" |
10 #include "src/hydrogen.h" | 10 #include "src/hydrogen.h" |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 HValue* number = GetParameter(NumberToStringStub::kNumber); | 292 HValue* number = GetParameter(NumberToStringStub::kNumber); |
293 return BuildNumberToString(number, Type::Number(zone())); | 293 return BuildNumberToString(number, Type::Number(zone())); |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 Handle<Code> NumberToStringStub::GenerateCode() { | 297 Handle<Code> NumberToStringStub::GenerateCode() { |
298 return DoGenerateCode(this); | 298 return DoGenerateCode(this); |
299 } | 299 } |
300 | 300 |
301 | 301 |
| 302 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). |
| 303 // Possible optimizations: put the type string into the oddballs. |
| 304 template <> |
| 305 HValue* CodeStubGraphBuilder<TypeofStub>::BuildCodeStub() { |
| 306 Factory* factory = isolate()->factory(); |
| 307 HConstant* number_string = Add<HConstant>(factory->number_string()); |
| 308 HValue* object = GetParameter(TypeofStub::kObject); |
| 309 |
| 310 IfBuilder is_smi(this); |
| 311 HValue* smi_check = is_smi.If<HIsSmiAndBranch>(object); |
| 312 is_smi.Then(); |
| 313 { Push(number_string); } |
| 314 is_smi.Else(); |
| 315 { |
| 316 IfBuilder is_number(this); |
| 317 is_number.If<HCompareMap>(object, isolate()->factory()->heap_number_map()); |
| 318 is_number.Then(); |
| 319 { Push(number_string); } |
| 320 is_number.Else(); |
| 321 { |
| 322 HConstant* undefined_string = Add<HConstant>(factory->undefined_string()); |
| 323 HValue* map = AddLoadMap(object, smi_check); |
| 324 HValue* instance_type = Add<HLoadNamedField>( |
| 325 map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 326 IfBuilder is_string(this); |
| 327 is_string.If<HCompareNumericAndBranch>( |
| 328 instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE), Token::LT); |
| 329 is_string.Then(); |
| 330 { Push(Add<HConstant>(factory->string_string())); } |
| 331 is_string.Else(); |
| 332 { |
| 333 HConstant* object_string = Add<HConstant>(factory->object_string()); |
| 334 IfBuilder is_oddball(this); |
| 335 is_oddball.If<HCompareNumericAndBranch>( |
| 336 instance_type, Add<HConstant>(ODDBALL_TYPE), Token::EQ); |
| 337 is_oddball.Then(); |
| 338 { |
| 339 IfBuilder is_true_or_false(this); |
| 340 is_true_or_false.If<HCompareObjectEqAndBranch>( |
| 341 object, graph()->GetConstantTrue()); |
| 342 is_true_or_false.OrIf<HCompareObjectEqAndBranch>( |
| 343 object, graph()->GetConstantFalse()); |
| 344 is_true_or_false.Then(); |
| 345 { Push(Add<HConstant>(factory->boolean_string())); } |
| 346 is_true_or_false.Else(); |
| 347 { |
| 348 IfBuilder is_null(this); |
| 349 is_null.If<HCompareObjectEqAndBranch>(object, |
| 350 graph()->GetConstantNull()); |
| 351 is_null.Then(); |
| 352 { Push(object_string); } |
| 353 is_null.Else(); |
| 354 { Push(undefined_string); } |
| 355 } |
| 356 is_true_or_false.End(); |
| 357 } |
| 358 is_oddball.Else(); |
| 359 { |
| 360 IfBuilder is_symbol(this); |
| 361 is_symbol.If<HCompareNumericAndBranch>( |
| 362 instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ); |
| 363 is_symbol.Then(); |
| 364 { Push(Add<HConstant>(factory->symbol_string())); } |
| 365 is_symbol.Else(); |
| 366 { |
| 367 IfBuilder is_function(this); |
| 368 HConstant* js_function = Add<HConstant>(JS_FUNCTION_TYPE); |
| 369 HConstant* js_function_proxy = |
| 370 Add<HConstant>(JS_FUNCTION_PROXY_TYPE); |
| 371 is_function.If<HCompareNumericAndBranch>(instance_type, js_function, |
| 372 Token::EQ); |
| 373 is_function.OrIf<HCompareNumericAndBranch>( |
| 374 instance_type, js_function_proxy, Token::EQ); |
| 375 is_function.Then(); |
| 376 { Push(Add<HConstant>(factory->function_string())); } |
| 377 is_function.Else(); |
| 378 { |
| 379 // Is it an undetectable object? |
| 380 IfBuilder is_undetectable(this); |
| 381 is_undetectable.If<HIsUndetectableAndBranch>(object); |
| 382 is_undetectable.Then(); |
| 383 { |
| 384 // typeof an undetectable object is 'undefined'. |
| 385 Push(undefined_string); |
| 386 } |
| 387 is_undetectable.Else(); |
| 388 { |
| 389 // For any kind of object not handled above, the spec rule for |
| 390 // host objects gives that it is okay to return "object". |
| 391 Push(object_string); |
| 392 } |
| 393 } |
| 394 is_function.End(); |
| 395 } |
| 396 is_symbol.End(); |
| 397 } |
| 398 is_oddball.End(); |
| 399 } |
| 400 is_string.End(); |
| 401 } |
| 402 is_number.End(); |
| 403 } |
| 404 is_smi.End(); |
| 405 |
| 406 return environment()->Pop(); |
| 407 } |
| 408 |
| 409 |
| 410 Handle<Code> TypeofStub::GenerateCode() { return DoGenerateCode(this); } |
| 411 |
| 412 |
302 template <> | 413 template <> |
303 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { | 414 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
304 Factory* factory = isolate()->factory(); | 415 Factory* factory = isolate()->factory(); |
305 HValue* undefined = graph()->GetConstantUndefined(); | 416 HValue* undefined = graph()->GetConstantUndefined(); |
306 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); | 417 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); |
307 | 418 |
308 // This stub is very performance sensitive, the generated code must be tuned | 419 // This stub is very performance sensitive, the generated code must be tuned |
309 // so that it doesn't build and eager frame. | 420 // so that it doesn't build and eager frame. |
310 info()->MarkMustNotHaveEagerFrame(); | 421 info()->MarkMustNotHaveEagerFrame(); |
311 | 422 |
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2112 // need. | 2223 // need. |
2113 info()->MarkMustNotHaveEagerFrame(); | 2224 info()->MarkMustNotHaveEagerFrame(); |
2114 | 2225 |
2115 // Probe the stub cache. | 2226 // Probe the stub cache. |
2116 Add<HTailCallThroughMegamorphicCache>(receiver, name); | 2227 Add<HTailCallThroughMegamorphicCache>(receiver, name); |
2117 | 2228 |
2118 // We never continue. | 2229 // We never continue. |
2119 return graph()->GetConstant0(); | 2230 return graph()->GetConstant0(); |
2120 } | 2231 } |
2121 } } // namespace v8::internal | 2232 } } // namespace v8::internal |
OLD | NEW |