Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/js-global-specialization.h" | 5 #include "src/compiler/js-global-specialization.h" |
| 6 | 6 |
| 7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/js-operator.h" | 10 #include "src/compiler/js-operator.h" |
| 11 #include "src/contexts.h" | 11 #include "src/contexts.h" |
| 12 #include "src/field-index-inl.h" | |
| 12 #include "src/lookup.h" | 13 #include "src/lookup.h" |
| 13 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker! | 14 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker! |
| 15 #include "src/type-feedback-vector.h" | |
| 14 | 16 |
| 15 namespace v8 { | 17 namespace v8 { |
| 16 namespace internal { | 18 namespace internal { |
| 17 namespace compiler { | 19 namespace compiler { |
| 18 | 20 |
| 19 struct JSGlobalSpecialization::ScriptContextTableLookupResult { | 21 struct JSGlobalSpecialization::ScriptContextTableLookupResult { |
| 20 Handle<Context> context; | 22 Handle<Context> context; |
| 21 bool immutable; | 23 bool immutable; |
| 22 int index; | 24 int index; |
| 23 }; | 25 }; |
| 24 | 26 |
| 25 | 27 |
| 26 JSGlobalSpecialization::JSGlobalSpecialization( | 28 JSGlobalSpecialization::JSGlobalSpecialization( |
| 27 Editor* editor, JSGraph* jsgraph, Flags flags, | 29 Editor* editor, JSGraph* jsgraph, Flags flags, |
| 28 Handle<GlobalObject> global_object, CompilationDependencies* dependencies) | 30 Handle<GlobalObject> global_object, CompilationDependencies* dependencies, |
| 31 Zone* zone) | |
| 29 : AdvancedReducer(editor), | 32 : AdvancedReducer(editor), |
| 30 jsgraph_(jsgraph), | 33 jsgraph_(jsgraph), |
| 31 flags_(flags), | 34 flags_(flags), |
| 32 global_object_(global_object), | 35 global_object_(global_object), |
| 33 dependencies_(dependencies), | 36 dependencies_(dependencies), |
| 34 simplified_(graph()->zone()) {} | 37 simplified_(graph()->zone()), |
| 38 zone_(zone) {} | |
| 35 | 39 |
| 36 | 40 |
| 37 Reduction JSGlobalSpecialization::Reduce(Node* node) { | 41 Reduction JSGlobalSpecialization::Reduce(Node* node) { |
| 38 switch (node->opcode()) { | 42 switch (node->opcode()) { |
| 39 case IrOpcode::kJSLoadGlobal: | 43 case IrOpcode::kJSLoadGlobal: |
| 40 return ReduceJSLoadGlobal(node); | 44 return ReduceJSLoadGlobal(node); |
| 41 case IrOpcode::kJSStoreGlobal: | 45 case IrOpcode::kJSStoreGlobal: |
| 42 return ReduceJSStoreGlobal(node); | 46 return ReduceJSStoreGlobal(node); |
| 47 case IrOpcode::kJSLoadNamed: | |
| 48 return ReduceJSLoadNamed(node); | |
| 43 default: | 49 default: |
| 44 break; | 50 break; |
| 45 } | 51 } |
| 46 return NoChange(); | 52 return NoChange(); |
| 47 } | 53 } |
| 48 | 54 |
| 49 | 55 |
| 50 Reduction JSGlobalSpecialization::ReduceJSLoadGlobal(Node* node) { | 56 Reduction JSGlobalSpecialization::ReduceJSLoadGlobal(Node* node) { |
| 51 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); | 57 DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode()); |
| 52 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); | 58 Handle<Name> name = LoadGlobalParametersOf(node->op()).name(); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 break; | 230 break; |
| 225 } | 231 } |
| 226 } | 232 } |
| 227 effect = graph()->NewNode( | 233 effect = graph()->NewNode( |
| 228 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), | 234 simplified()->StoreField(AccessBuilder::ForPropertyCellValue()), |
| 229 jsgraph()->Constant(property_cell), value, effect, control); | 235 jsgraph()->Constant(property_cell), value, effect, control); |
| 230 return Replace(node, value, effect, control); | 236 return Replace(node, value, effect, control); |
| 231 } | 237 } |
| 232 | 238 |
| 233 | 239 |
| 240 // This class encapsulates all information required to access a certain | |
| 241 // object property, either on the object itself or on the prototype chain. | |
| 242 class JSGlobalSpecialization::PropertyAccessInfo final { | |
| 243 public: | |
| 244 enum Kind { kInvalid, kData, kDataConstant }; | |
| 245 | |
| 246 static PropertyAccessInfo DataConstant(Type* receiver_type, | |
| 247 Handle<Object> constant, | |
| 248 MaybeHandle<JSObject> holder) { | |
| 249 return PropertyAccessInfo(holder, constant, receiver_type); | |
| 250 } | |
| 251 static PropertyAccessInfo Data(Type* receiver_type, FieldIndex field_index, | |
| 252 Representation field_representation, | |
| 253 MaybeHandle<JSObject> holder) { | |
| 254 return PropertyAccessInfo(holder, field_index, field_representation, | |
| 255 receiver_type); | |
| 256 } | |
| 257 | |
| 258 PropertyAccessInfo() : kind_(kInvalid) {} | |
| 259 PropertyAccessInfo(MaybeHandle<JSObject> holder, Handle<Object> constant, | |
| 260 Type* receiver_type) | |
| 261 : kind_(kDataConstant), | |
| 262 receiver_type_(receiver_type), | |
| 263 constant_(constant), | |
| 264 holder_(holder) {} | |
| 265 PropertyAccessInfo(MaybeHandle<JSObject> holder, FieldIndex field_index, | |
| 266 Representation field_representation, Type* receiver_type) | |
| 267 : kind_(kData), | |
| 268 receiver_type_(receiver_type), | |
| 269 holder_(holder), | |
| 270 field_index_(field_index), | |
| 271 field_representation_(field_representation) {} | |
| 272 | |
| 273 bool IsDataConstant() const { return kind() == kDataConstant; } | |
| 274 bool IsData() const { return kind() == kData; } | |
| 275 | |
| 276 Kind kind() const { return kind_; } | |
| 277 MaybeHandle<JSObject> holder() const { return holder_; } | |
| 278 Handle<Object> constant() const { return constant_; } | |
| 279 FieldIndex field_index() const { return field_index_; } | |
| 280 Representation field_representation() const { return field_representation_; } | |
| 281 Type* receiver_type() const { return receiver_type_; } | |
| 282 | |
| 283 private: | |
| 284 Kind kind_; | |
| 285 Type* receiver_type_; | |
| 286 Handle<Object> constant_; | |
| 287 MaybeHandle<JSObject> holder_; | |
| 288 FieldIndex field_index_; | |
| 289 Representation field_representation_; | |
| 290 }; | |
| 291 | |
| 292 | |
| 293 namespace { | |
| 294 | |
| 295 bool CanInlinePropertyAccess(Handle<Map> map) { | |
| 296 // TODO(bmeurer): Do something about the number stuff. | |
| 297 if (map->instance_type() == HEAP_NUMBER_TYPE) return false; | |
| 298 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; | |
| 299 return map->IsJSObjectMap() && !map->is_dictionary_map() && | |
| 300 !map->has_named_interceptor() && | |
| 301 // TODO(verwaest): Whitelist contexts to which we have access. | |
| 302 !map->is_access_check_needed(); | |
| 303 } | |
| 304 | |
| 305 } // namespace | |
| 306 | |
| 307 | |
| 308 bool JSGlobalSpecialization::ComputePropertyAccessInfo( | |
| 309 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* info) { | |
| 310 MaybeHandle<JSObject> holder; | |
| 311 Type* receiver_type = Type::Class(map, graph()->zone()); | |
| 312 while (CanInlinePropertyAccess(map)) { | |
| 313 // Lookup the named property on the {map}. | |
| 314 Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); | |
| 315 int const number = descriptors->SearchWithCache(*name, *map); | |
| 316 if (number != DescriptorArray::kNotFound) { | |
| 317 PropertyDetails const details = descriptors->GetDetails(number); | |
| 318 if (details.type() == DATA_CONSTANT) { | |
| 319 *info = PropertyAccessInfo::DataConstant( | |
| 320 receiver_type, handle(descriptors->GetValue(number), isolate()), | |
| 321 holder); | |
| 322 return true; | |
| 323 } else if (details.type() == DATA) { | |
| 324 int index = descriptors->GetFieldIndex(number); | |
| 325 Representation field_representation = details.representation(); | |
| 326 FieldIndex field_index = FieldIndex::ForPropertyIndex( | |
| 327 *map, index, field_representation.IsDouble()); | |
| 328 *info = PropertyAccessInfo::Data(receiver_type, field_index, | |
| 329 field_representation, holder); | |
| 330 return true; | |
| 331 } else { | |
| 332 // TODO(bmeurer): Add support for accessors. | |
| 333 break; | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 // Don't search on the prototype chain for special indices in case of | |
| 338 // integer indexed exotic objects (see ES6 section 9.4.5). | |
| 339 if (map->IsJSTypedArrayMap() && name->IsString() && | |
| 340 IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) { | |
| 341 break; | |
| 342 } | |
| 343 | |
| 344 // Walk up the prototype chain. | |
| 345 if (!map->prototype()->IsJSObject()) { | |
| 346 // TODO(bmeurer): Handle the not found case if the prototype is null. | |
| 347 break; | |
| 348 } | |
| 349 Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate()); | |
| 350 if (map_prototype->map()->is_deprecated()) { | |
| 351 // Try to migrate the prototype object so we don't embed the deprecated | |
| 352 // map into the optimized code. | |
| 353 JSObject::TryMigrateInstance(map_prototype); | |
| 354 } | |
| 355 map = handle(map_prototype->map(), isolate()); | |
| 356 holder = map_prototype; | |
| 357 } | |
| 358 return false; | |
| 359 } | |
| 360 | |
| 361 | |
| 362 bool JSGlobalSpecialization::ComputePropertyAccessInfos( | |
| 363 MapHandleList const& maps, Handle<Name> name, | |
| 364 ZoneVector<PropertyAccessInfo>* infos) { | |
| 365 for (Handle<Map> map : maps) { | |
| 366 PropertyAccessInfo info; | |
| 367 if (!ComputePropertyAccessInfo(map, name, &info)) return false; | |
| 368 infos->push_back(info); | |
| 369 } | |
| 370 return true; | |
| 371 } | |
| 372 | |
| 373 | |
| 374 Reduction JSGlobalSpecialization::ReduceJSLoadNamed(Node* node) { | |
|
Jarin
2015/10/16 12:33:09
Could we rename the file/class, please?
Benedikt Meurer
2015/10/16 13:22:15
As discussed offline: Separate CL :-)
| |
| 375 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | |
| 376 LoadNamedParameters const p = LoadNamedParametersOf(node->op()); | |
| 377 Handle<Name> name = p.name(); | |
| 378 Node* receiver = NodeProperties::GetValueInput(node, 0); | |
| 379 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | |
| 380 Node* effect = NodeProperties::GetEffectInput(node); | |
| 381 Node* control = NodeProperties::GetControlInput(node); | |
| 382 | |
| 383 // Not much we can do if deoptimization support is disabled. | |
| 384 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | |
| 385 | |
| 386 // Extract receiver maps from the LOAD_IC using the LoadICNexus. | |
| 387 MapHandleList receiver_maps; | |
| 388 if (!p.feedback().IsValid()) return NoChange(); | |
| 389 LoadICNexus nexus(p.feedback().vector(), p.feedback().slot()); | |
| 390 if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange(); | |
| 391 DCHECK_LT(0, receiver_maps.length()); | |
| 392 | |
| 393 // Compute property access infos for the receiver maps. | |
| 394 ZoneVector<PropertyAccessInfo> infos(zone()); | |
| 395 if (!ComputePropertyAccessInfos(receiver_maps, name, &infos)) { | |
| 396 return NoChange(); | |
| 397 } | |
| 398 DCHECK(!infos.empty()); | |
| 399 | |
| 400 // The final states for every polymorphic branch. We join them with | |
| 401 // Merge+Phi+EffectPhi at the bottom. | |
| 402 ZoneVector<Node*> values(zone()); | |
| 403 ZoneVector<Node*> effects(zone()); | |
| 404 ZoneVector<Node*> controls(zone()); | |
| 405 | |
| 406 // The list of "exiting" controls, which currently go to a single deoptimize. | |
| 407 // TODO(bmeurer): Consider using an IC as fallback. | |
| 408 Node* const exit_effect = effect; | |
| 409 ZoneVector<Node*> exit_controls(zone()); | |
| 410 | |
| 411 // Ensure that {receiver} is a heap object. | |
| 412 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); | |
| 413 Node* branch = | |
| 414 graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); | |
| 415 exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); | |
| 416 control = graph()->NewNode(common()->IfFalse(), branch); | |
| 417 | |
| 418 // Load the {receiver} map. The resulting effect is the dominating effect for | |
| 419 // all (polymorphic) branches. | |
| 420 Node* receiver_map = effect = | |
| 421 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | |
| 422 receiver, effect, control); | |
| 423 | |
| 424 // Generate code for the various different property access patterns. | |
| 425 for (PropertyAccessInfo const& info : infos) { | |
|
Jarin
2015/10/16 12:33:09
info -> access_info?
In general, names in this me
Benedikt Meurer
2015/10/16 13:22:15
Done.
| |
| 426 Node* this_value = receiver; | |
| 427 Node* this_effect = effect; | |
| 428 Node* this_control; | |
| 429 | |
| 430 // Perform map check on {receiver}. | |
| 431 Type* receiver_type = info.receiver_type(); | |
| 432 if (receiver_type->Is(Type::String())) { | |
| 433 // Emit an instance type check for strings. | |
| 434 Node* receiver_instance_type = this_effect = graph()->NewNode( | |
| 435 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), | |
| 436 receiver_map, this_effect, control); | |
| 437 Node* check = | |
| 438 graph()->NewNode(machine()->Uint32LessThan(), receiver_instance_type, | |
| 439 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); | |
| 440 Node* branch = | |
| 441 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | |
| 442 control = graph()->NewNode(common()->IfFalse(), branch); | |
|
Jarin
2015/10/16 12:33:09
control -> exit_control? or maybe even check_fail_
Benedikt Meurer
2015/10/16 13:22:15
Ok, renamed to fallthrough_control as discussed of
| |
| 443 this_control = graph()->NewNode(common()->IfTrue(), branch); | |
| 444 } else { | |
| 445 // Emit a (sequence of) map checks for other properties. | |
| 446 ZoneVector<Node*> this_controls(zone()); | |
| 447 for (auto i = info.receiver_type()->Classes(); !i.Done(); i.Advance()) { | |
| 448 Handle<Map> map = i.Current(); | |
| 449 Node* check = | |
| 450 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), | |
| 451 receiver_map, jsgraph()->Constant(map)); | |
| 452 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 453 check, control); | |
| 454 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); | |
| 455 control = graph()->NewNode(common()->IfFalse(), branch); | |
| 456 } | |
| 457 int const this_control_count = static_cast<int>(this_controls.size()); | |
| 458 this_control = | |
| 459 (this_control_count == 1) | |
| 460 ? this_controls.front() | |
| 461 : graph()->NewNode(common()->Merge(this_control_count), | |
| 462 this_control_count, &this_controls.front()); | |
| 463 } | |
| 464 | |
| 465 // Determine actual holder and perform prototype chain checks. | |
| 466 Handle<JSObject> holder; | |
| 467 if (info.holder().ToHandle(&holder)) { | |
| 468 this_value = jsgraph()->Constant(holder); | |
| 469 for (auto i = info.receiver_type()->Classes(); !i.Done(); i.Advance()) { | |
| 470 Handle<Map> map = i.Current(); | |
| 471 PrototypeIterator j(map); | |
| 472 while (true) { | |
| 473 // Check that the {prototype} still has the same map. For stable | |
| 474 // maps, we can add a stability dependency on the prototype map; | |
| 475 // for everything else we need to perform a map check at runtime. | |
| 476 Handle<JSReceiver> prototype = | |
| 477 PrototypeIterator::GetCurrent<JSReceiver>(j); | |
| 478 if (prototype->map()->is_stable()) { | |
| 479 dependencies()->AssumeMapStable( | |
| 480 handle(prototype->map(), isolate())); | |
| 481 } else { | |
| 482 Node* prototype_map = this_effect = graph()->NewNode( | |
| 483 simplified()->LoadField(AccessBuilder::ForMap()), | |
| 484 jsgraph()->Constant(prototype), this_effect, this_control); | |
| 485 Node* check = graph()->NewNode( | |
| 486 simplified()->ReferenceEqual(Type::Internal()), prototype_map, | |
| 487 jsgraph()->Constant(handle(prototype->map(), isolate()))); | |
| 488 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
| 489 check, this_control); | |
| 490 exit_controls.push_back( | |
| 491 graph()->NewNode(common()->IfFalse(), branch)); | |
| 492 this_control = graph()->NewNode(common()->IfTrue(), branch); | |
| 493 } | |
| 494 // Stop once we get to the holder. | |
| 495 if (prototype.is_identical_to(holder)) break; | |
| 496 j.Advance(); | |
| 497 } | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 // Generate the actual property access. | |
| 502 if (info.IsDataConstant()) { | |
| 503 this_value = jsgraph()->Constant(info.constant()); | |
| 504 } else { | |
| 505 // TODO(bmeurer): This is sort of adhoc, and must be refactored into some | |
| 506 // common code once we also have support for stores. | |
| 507 DCHECK(info.IsData()); | |
| 508 FieldIndex const field_index = info.field_index(); | |
| 509 Representation const field_representation = info.field_representation(); | |
| 510 if (!field_index.is_inobject()) { | |
| 511 this_value = this_effect = graph()->NewNode( | |
| 512 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), | |
| 513 this_value, this_effect, this_control); | |
| 514 } | |
| 515 FieldAccess field_access; | |
| 516 field_access.base_is_tagged = kTaggedBase; | |
| 517 field_access.offset = field_index.offset(); | |
| 518 field_access.name = name; | |
| 519 field_access.type = Type::Any(); | |
| 520 field_access.machine_type = kMachAnyTagged; | |
| 521 if (field_representation.IsSmi()) { | |
| 522 field_access.type = Type::Intersect( | |
| 523 Type::SignedSmall(), Type::TaggedSigned(), graph()->zone()); | |
| 524 } else if (field_representation.IsDouble()) { | |
| 525 if (!field_index.is_inobject() || field_index.is_hidden_field() || | |
| 526 !FLAG_unbox_double_fields) { | |
| 527 this_value = this_effect = | |
| 528 graph()->NewNode(simplified()->LoadField(field_access), | |
| 529 this_value, this_effect, this_control); | |
| 530 field_access.offset = HeapNumber::kValueOffset; | |
| 531 field_access.name = MaybeHandle<Name>(); | |
| 532 } | |
| 533 field_access.type = Type::Intersect( | |
| 534 Type::Number(), Type::UntaggedFloat64(), graph()->zone()); | |
| 535 field_access.machine_type = kMachFloat64; | |
| 536 } else if (field_representation.IsHeapObject()) { | |
| 537 field_access.type = Type::TaggedPointer(); | |
| 538 } | |
| 539 this_value = this_effect = | |
| 540 graph()->NewNode(simplified()->LoadField(field_access), this_value, | |
| 541 this_effect, this_control); | |
| 542 } | |
| 543 | |
| 544 // Remember the final state for this property access. | |
| 545 values.push_back(this_value); | |
| 546 effects.push_back(this_effect); | |
| 547 controls.push_back(this_control); | |
| 548 } | |
| 549 | |
| 550 // Generate the single "exit" point. | |
|
Jarin
2015/10/16 12:33:09
Please better comment here. It should say that we
Benedikt Meurer
2015/10/16 13:22:15
Done.
| |
| 551 exit_controls.push_back(control); | |
| 552 int const exit_control_count = static_cast<int>(exit_controls.size()); | |
| 553 Node* exit_control = | |
| 554 (exit_control_count == 1) | |
| 555 ? exit_controls.front() | |
| 556 : graph()->NewNode(common()->Merge(exit_control_count), | |
| 557 exit_control_count, &exit_controls.front()); | |
| 558 Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state, | |
| 559 exit_effect, exit_control); | |
| 560 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | |
| 561 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | |
| 562 | |
| 563 // Generate the final merge point for all (polymorphic) branches. | |
| 564 Node* value; | |
| 565 int const control_count = static_cast<int>(controls.size()); | |
| 566 if (control_count == 1) { | |
| 567 value = values.front(); | |
| 568 effect = effects.front(); | |
| 569 control = controls.front(); | |
| 570 } else { | |
| 571 control = graph()->NewNode(common()->Merge(control_count), control_count, | |
| 572 &controls.front()); | |
| 573 values.push_back(control); | |
| 574 value = graph()->NewNode(common()->Phi(kMachAnyTagged, control_count), | |
| 575 control_count + 1, &values.front()); | |
| 576 effects.push_back(control); | |
| 577 effect = graph()->NewNode(common()->EffectPhi(control_count), | |
| 578 control_count + 1, &effects.front()); | |
| 579 } | |
| 580 return Replace(node, value, effect, control); | |
| 581 } | |
| 582 | |
| 583 | |
| 234 Reduction JSGlobalSpecialization::Replace(Node* node, Handle<Object> value) { | 584 Reduction JSGlobalSpecialization::Replace(Node* node, Handle<Object> value) { |
| 235 // TODO(bmeurer): Move this to JSGraph::HeapConstant instead? | |
| 236 if (value->IsConsString()) { | |
| 237 value = String::Flatten(Handle<String>::cast(value), TENURED); | |
| 238 } | |
| 239 return Replace(node, jsgraph()->Constant(value)); | 585 return Replace(node, jsgraph()->Constant(value)); |
| 240 } | 586 } |
| 241 | 587 |
| 242 | 588 |
| 243 bool JSGlobalSpecialization::LookupInScriptContextTable( | 589 bool JSGlobalSpecialization::LookupInScriptContextTable( |
| 244 Handle<Name> name, ScriptContextTableLookupResult* result) { | 590 Handle<Name> name, ScriptContextTableLookupResult* result) { |
| 245 if (!name->IsString()) return false; | 591 if (!name->IsString()) return false; |
| 246 Handle<ScriptContextTable> script_context_table( | 592 Handle<ScriptContextTable> script_context_table( |
| 247 global_object()->native_context()->script_context_table()); | 593 global_object()->native_context()->script_context_table()); |
| 248 ScriptContextTable::LookupResult lookup_result; | 594 ScriptContextTable::LookupResult lookup_result; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 261 | 607 |
| 262 | 608 |
| 263 Graph* JSGlobalSpecialization::graph() const { return jsgraph()->graph(); } | 609 Graph* JSGlobalSpecialization::graph() const { return jsgraph()->graph(); } |
| 264 | 610 |
| 265 | 611 |
| 266 Isolate* JSGlobalSpecialization::isolate() const { | 612 Isolate* JSGlobalSpecialization::isolate() const { |
| 267 return jsgraph()->isolate(); | 613 return jsgraph()->isolate(); |
| 268 } | 614 } |
| 269 | 615 |
| 270 | 616 |
| 617 MachineOperatorBuilder* JSGlobalSpecialization::machine() const { | |
| 618 return jsgraph()->machine(); | |
| 619 } | |
| 620 | |
| 621 | |
| 271 CommonOperatorBuilder* JSGlobalSpecialization::common() const { | 622 CommonOperatorBuilder* JSGlobalSpecialization::common() const { |
| 272 return jsgraph()->common(); | 623 return jsgraph()->common(); |
| 273 } | 624 } |
| 274 | 625 |
| 275 | 626 |
| 276 JSOperatorBuilder* JSGlobalSpecialization::javascript() const { | 627 JSOperatorBuilder* JSGlobalSpecialization::javascript() const { |
| 277 return jsgraph()->javascript(); | 628 return jsgraph()->javascript(); |
| 278 } | 629 } |
| 279 | 630 |
| 280 } // namespace compiler | 631 } // namespace compiler |
| 281 } // namespace internal | 632 } // namespace internal |
| 282 } // namespace v8 | 633 } // namespace v8 |
| OLD | NEW |