Revision f230a1cf deps/v8/src/code-stubs-hydrogen.cc
deps/v8/src/code-stubs-hydrogen.cc | ||
---|---|---|
146 | 146 |
int param_count = descriptor_->register_param_count_; |
147 | 147 |
HEnvironment* start_environment = graph()->start_environment(); |
148 | 148 |
HBasicBlock* next_block = CreateBasicBlock(start_environment); |
149 |
current_block()->Goto(next_block);
|
|
149 |
Goto(next_block); |
|
150 | 150 |
next_block->SetJoinId(BailoutId::StubEntry()); |
151 | 151 |
set_current_block(next_block); |
152 | 152 |
|
153 |
HConstant* undefined_constant = |
|
154 |
Add<HConstant>(isolate()->factory()->undefined_value()); |
|
155 |
graph()->set_undefined_constant(undefined_constant); |
|
156 |
|
|
157 | 153 |
for (int i = 0; i < param_count; ++i) { |
158 | 154 |
HParameter* param = |
159 | 155 |
Add<HParameter>(i, HParameter::REGISTER_PARAMETER); |
... | ... | |
162 | 158 |
} |
163 | 159 |
|
164 | 160 |
HInstruction* stack_parameter_count; |
165 |
if (descriptor_->stack_parameter_count_ != NULL) {
|
|
161 |
if (descriptor_->stack_parameter_count_.is_valid()) {
|
|
166 | 162 |
ASSERT(descriptor_->environment_length() == (param_count + 1)); |
167 | 163 |
stack_parameter_count = New<HParameter>(param_count, |
168 | 164 |
HParameter::REGISTER_PARAMETER, |
... | ... | |
178 | 174 |
arguments_length_ = graph()->GetConstant0(); |
179 | 175 |
} |
180 | 176 |
|
181 |
context_ = New<HContext>(); |
|
182 |
AddInstruction(context_); |
|
177 |
context_ = Add<HContext>(); |
|
183 | 178 |
start_environment->BindContext(context_); |
184 | 179 |
|
185 | 180 |
Add<HSimulate>(BailoutId::StubEntry()); |
... | ... | |
207 | 202 |
if (current_block() != NULL) { |
208 | 203 |
HReturn* hreturn_instruction = New<HReturn>(return_value, |
209 | 204 |
stack_pop_count); |
210 |
current_block()->Finish(hreturn_instruction); |
|
211 |
set_current_block(NULL); |
|
205 |
FinishCurrentBlock(hreturn_instruction); |
|
212 | 206 |
} |
213 | 207 |
return true; |
214 | 208 |
} |
... | ... | |
298 | 292 |
// the runtime that is significantly faster than using the standard |
299 | 293 |
// stub-failure deopt mechanism. |
300 | 294 |
if (stub->IsUninitialized() && descriptor->has_miss_handler()) { |
301 |
ASSERT(descriptor->stack_parameter_count_ == NULL);
|
|
295 |
ASSERT(!descriptor->stack_parameter_count_.is_valid());
|
|
302 | 296 |
return stub->GenerateLightweightMissCode(isolate); |
303 | 297 |
} |
298 |
ElapsedTimer timer; |
|
299 |
if (FLAG_profile_hydrogen_code_stub_compilation) { |
|
300 |
timer.Start(); |
|
301 |
} |
|
304 | 302 |
CodeStubGraphBuilder<Stub> builder(isolate, stub); |
305 | 303 |
LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
306 |
return chunk->Codegen(); |
|
304 |
Handle<Code> code = chunk->Codegen(); |
|
305 |
if (FLAG_profile_hydrogen_code_stub_compilation) { |
|
306 |
double ms = timer.Elapsed().InMillisecondsF(); |
|
307 |
PrintF("[Lazy compilation of %s took %0.3f ms]\n", *stub->GetName(), ms); |
|
308 |
} |
|
309 |
return code; |
|
307 | 310 |
} |
308 | 311 |
|
309 | 312 |
|
... | ... | |
339 | 342 |
|
340 | 343 |
|
341 | 344 |
template <> |
345 |
HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() { |
|
346 |
info()->MarkAsSavesCallerDoubles(); |
|
347 |
HValue* number = GetParameter(NumberToStringStub::kNumber); |
|
348 |
return BuildNumberToString(number, handle(Type::Number(), isolate())); |
|
349 |
} |
|
350 |
|
|
351 |
|
|
352 |
Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) { |
|
353 |
return DoGenerateCode(isolate, this); |
|
354 |
} |
|
355 |
|
|
356 |
|
|
357 |
template <> |
|
342 | 358 |
HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { |
343 | 359 |
Factory* factory = isolate()->factory(); |
344 | 360 |
HValue* undefined = graph()->GetConstantUndefined(); |
... | ... | |
355 | 371 |
undefined); |
356 | 372 |
checker.Then(); |
357 | 373 |
|
358 |
HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo(); |
|
374 |
HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
|
375 |
AllocationSite::kTransitionInfoOffset); |
|
359 | 376 |
HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access); |
377 |
HValue* push_value; |
|
360 | 378 |
if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { |
361 | 379 |
HValue* elements = AddLoadElements(boilerplate); |
362 | 380 |
|
363 | 381 |
IfBuilder if_fixed_cow(this); |
364 | 382 |
if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); |
365 | 383 |
if_fixed_cow.Then(); |
366 |
environment()->Push(BuildCloneShallowArray(boilerplate, |
|
367 |
allocation_site, |
|
368 |
alloc_site_mode, |
|
369 |
FAST_ELEMENTS, |
|
370 |
0/*copy-on-write*/)); |
|
384 |
push_value = BuildCloneShallowArray(boilerplate, |
|
385 |
allocation_site, |
|
386 |
alloc_site_mode, |
|
387 |
FAST_ELEMENTS, |
|
388 |
0/*copy-on-write*/); |
|
389 |
environment()->Push(push_value); |
|
371 | 390 |
if_fixed_cow.Else(); |
372 | 391 |
|
373 | 392 |
IfBuilder if_fixed(this); |
374 | 393 |
if_fixed.If<HCompareMap>(elements, factory->fixed_array_map()); |
375 | 394 |
if_fixed.Then(); |
376 |
environment()->Push(BuildCloneShallowArray(boilerplate, |
|
377 |
allocation_site, |
|
378 |
alloc_site_mode, |
|
379 |
FAST_ELEMENTS, |
|
380 |
length)); |
|
395 |
push_value = BuildCloneShallowArray(boilerplate, |
|
396 |
allocation_site, |
|
397 |
alloc_site_mode, |
|
398 |
FAST_ELEMENTS, |
|
399 |
length); |
|
400 |
environment()->Push(push_value); |
|
381 | 401 |
if_fixed.Else(); |
382 |
environment()->Push(BuildCloneShallowArray(boilerplate, |
|
383 |
allocation_site, |
|
384 |
alloc_site_mode, |
|
385 |
FAST_DOUBLE_ELEMENTS, |
|
386 |
length)); |
|
402 |
push_value = BuildCloneShallowArray(boilerplate, |
|
403 |
allocation_site, |
|
404 |
alloc_site_mode, |
|
405 |
FAST_DOUBLE_ELEMENTS, |
|
406 |
length); |
|
407 |
environment()->Push(push_value); |
|
387 | 408 |
} else { |
388 | 409 |
ElementsKind elements_kind = casted_stub()->ComputeElementsKind(); |
389 |
environment()->Push(BuildCloneShallowArray(boilerplate, |
|
390 |
allocation_site, |
|
391 |
alloc_site_mode, |
|
392 |
elements_kind, |
|
393 |
length)); |
|
410 |
push_value = BuildCloneShallowArray(boilerplate, |
|
411 |
allocation_site, |
|
412 |
alloc_site_mode, |
|
413 |
elements_kind, |
|
414 |
length); |
|
415 |
environment()->Push(push_value); |
|
394 | 416 |
} |
395 | 417 |
|
396 | 418 |
checker.ElseDeopt("Uninitialized boilerplate literals"); |
... | ... | |
407 | 429 |
|
408 | 430 |
template <> |
409 | 431 |
HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { |
410 |
Zone* zone = this->zone(); |
|
411 | 432 |
HValue* undefined = graph()->GetConstantUndefined(); |
412 | 433 |
|
413 |
HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0),
|
|
414 |
GetParameter(1), |
|
415 |
static_cast<HValue*>(NULL), |
|
416 |
FAST_ELEMENTS); |
|
434 |
HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
|
|
435 |
GetParameter(1),
|
|
436 |
static_cast<HValue*>(NULL),
|
|
437 |
FAST_ELEMENTS);
|
|
417 | 438 |
|
418 | 439 |
IfBuilder checker(this); |
419 |
checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate,
|
|
440 |
checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
|
|
420 | 441 |
undefined); |
421 | 442 |
checker.And(); |
422 | 443 |
|
444 |
HObjectAccess access = HObjectAccess::ForAllocationSiteOffset( |
|
445 |
AllocationSite::kTransitionInfoOffset); |
|
446 |
HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access); |
|
447 |
|
|
423 | 448 |
int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; |
424 |
HValue* boilerplate_size = |
|
425 |
AddInstruction(new(zone) HInstanceSize(boilerplate)); |
|
426 |
HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2); |
|
449 |
int object_size = size; |
|
450 |
if (FLAG_allocation_site_pretenuring) { |
|
451 |
size += AllocationMemento::kSize; |
|
452 |
} |
|
453 |
|
|
454 |
HValue* boilerplate_map = Add<HLoadNamedField>( |
|
455 |
boilerplate, HObjectAccess::ForMap()); |
|
456 |
HValue* boilerplate_size = Add<HLoadNamedField>( |
|
457 |
boilerplate_map, HObjectAccess::ForMapInstanceSize()); |
|
458 |
HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2); |
|
427 | 459 |
checker.If<HCompareNumericAndBranch>(boilerplate_size, |
428 | 460 |
size_in_words, Token::EQ); |
429 | 461 |
checker.Then(); |
... | ... | |
433 | 465 |
HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), |
434 | 466 |
isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); |
435 | 467 |
|
436 |
for (int i = 0; i < size; i += kPointerSize) { |
|
468 |
for (int i = 0; i < object_size; i += kPointerSize) {
|
|
437 | 469 |
HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); |
438 | 470 |
Add<HStoreNamedField>(object, access, |
439 | 471 |
Add<HLoadNamedField>(boilerplate, access)); |
440 | 472 |
} |
441 | 473 |
|
474 |
ASSERT(FLAG_allocation_site_pretenuring || (size == object_size)); |
|
475 |
if (FLAG_allocation_site_pretenuring) { |
|
476 |
BuildCreateAllocationMemento(object, object_size, allocation_site); |
|
477 |
} |
|
478 |
|
|
442 | 479 |
environment()->Push(object); |
443 | 480 |
checker.ElseDeopt("Uninitialized boilerplate in fast clone"); |
444 | 481 |
checker.End(); |
... | ... | |
459 | 496 |
JS_OBJECT_TYPE); |
460 | 497 |
|
461 | 498 |
// Store the map |
462 |
Handle<Map> allocation_site_map(isolate()->heap()->allocation_site_map(), |
|
463 |
isolate()); |
|
499 |
Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map(); |
|
464 | 500 |
AddStoreMapConstant(object, allocation_site_map); |
465 | 501 |
|
466 | 502 |
// Store the payload (smi elements kind) |
467 | 503 |
HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind()); |
468 | 504 |
Add<HStoreNamedField>(object, |
469 |
HObjectAccess::ForAllocationSiteTransitionInfo(), |
|
505 |
HObjectAccess::ForAllocationSiteOffset( |
|
506 |
AllocationSite::kTransitionInfoOffset), |
|
470 | 507 |
initial_elements_kind); |
471 | 508 |
|
509 |
// Unlike literals, constructed arrays don't have nested sites |
|
510 |
Add<HStoreNamedField>(object, |
|
511 |
HObjectAccess::ForAllocationSiteOffset( |
|
512 |
AllocationSite::kNestedSiteOffset), |
|
513 |
graph()->GetConstant0()); |
|
514 |
|
|
515 |
// Store an empty fixed array for the code dependency. |
|
516 |
HConstant* empty_fixed_array = |
|
517 |
Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
|
518 |
HStoreNamedField* store = Add<HStoreNamedField>( |
|
519 |
object, |
|
520 |
HObjectAccess::ForAllocationSiteOffset( |
|
521 |
AllocationSite::kDependentCodeOffset), |
|
522 |
empty_fixed_array); |
|
523 |
|
|
472 | 524 |
// Link the object to the allocation site list |
473 | 525 |
HValue* site_list = Add<HConstant>( |
474 | 526 |
ExternalReference::allocation_sites_list_address(isolate())); |
475 | 527 |
HValue* site = Add<HLoadNamedField>(site_list, |
476 | 528 |
HObjectAccess::ForAllocationSiteList()); |
477 |
HStoreNamedField* store =
|
|
478 |
Add<HStoreNamedField>(object, HObjectAccess::ForAllocationSiteWeakNext(),
|
|
479 |
site);
|
|
529 |
store = Add<HStoreNamedField>(object,
|
|
530 |
HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
|
|
531 |
site); |
|
480 | 532 |
store->SkipWriteBarrier(); |
481 | 533 |
Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), |
482 | 534 |
object); |
... | ... | |
519 | 571 |
HObjectAccess access = casted_stub()->is_inobject() ? |
520 | 572 |
HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : |
521 | 573 |
HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); |
522 |
return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
|
|
574 |
return AddLoadNamedField(GetParameter(0), access);
|
|
523 | 575 |
} |
524 | 576 |
|
525 | 577 |
|
... | ... | |
534 | 586 |
HObjectAccess access = casted_stub()->is_inobject() ? |
535 | 587 |
HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : |
536 | 588 |
HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); |
537 |
return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
|
|
589 |
return AddLoadNamedField(GetParameter(0), access);
|
|
538 | 590 |
} |
539 | 591 |
|
540 | 592 |
|
... | ... | |
640 | 692 |
HValue* constant_zero = graph()->GetConstant0(); |
641 | 693 |
|
642 | 694 |
HInstruction* elements = Add<HArgumentsElements>(false); |
643 |
HInstruction* argument = AddInstruction(
|
|
644 |
new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero));
|
|
695 |
HInstruction* argument = Add<HAccessArgumentsAt>(
|
|
696 |
elements, constant_one, constant_zero);
|
|
645 | 697 |
|
646 | 698 |
HConstant* max_alloc_length = |
647 | 699 |
Add<HConstant>(JSObject::kInitialMaxFastElementArray); |
648 | 700 |
const int initial_capacity = JSArray::kPreallocatedArrayElements; |
649 |
HConstant* initial_capacity_node = New<HConstant>(initial_capacity); |
|
650 |
AddInstruction(initial_capacity_node); |
|
701 |
HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); |
|
651 | 702 |
|
652 | 703 |
HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length); |
653 | 704 |
IfBuilder if_builder(this); |
... | ... | |
690 | 741 |
HValue* start = graph()->GetConstant0(); |
691 | 742 |
HValue* key = builder.BeginBody(start, length, Token::LT); |
692 | 743 |
HInstruction* argument_elements = Add<HArgumentsElements>(false); |
693 |
HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt(
|
|
694 |
argument_elements, length, key));
|
|
744 |
HInstruction* argument = Add<HAccessArgumentsAt>(
|
|
745 |
argument_elements, length, key); |
|
695 | 746 |
|
696 | 747 |
Add<HStoreKeyed>(elements, key, argument, kind); |
697 | 748 |
builder.EndBody(); |
... | ... | |
792 | 843 |
HIfContinuation continuation; |
793 | 844 |
Handle<Map> sentinel_map(isolate->heap()->meta_map()); |
794 | 845 |
Handle<Type> type = stub->GetType(isolate, sentinel_map); |
795 |
BuildCompareNil(GetParameter(0), type, RelocInfo::kNoPosition, &continuation);
|
|
846 |
BuildCompareNil(GetParameter(0), type, &continuation); |
|
796 | 847 |
IfBuilder if_nil(this, &continuation); |
797 | 848 |
if_nil.Then(); |
798 | 849 |
if (continuation.IsFalseReachable()) { |
... | ... | |
812 | 863 |
|
813 | 864 |
|
814 | 865 |
template <> |
866 |
HValue* CodeStubGraphBuilder<BinaryOpStub>::BuildCodeInitializedStub() { |
|
867 |
BinaryOpStub* stub = casted_stub(); |
|
868 |
HValue* left = GetParameter(0); |
|
869 |
HValue* right = GetParameter(1); |
|
870 |
|
|
871 |
Handle<Type> left_type = stub->GetLeftType(isolate()); |
|
872 |
Handle<Type> right_type = stub->GetRightType(isolate()); |
|
873 |
Handle<Type> result_type = stub->GetResultType(isolate()); |
|
874 |
|
|
875 |
ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && |
|
876 |
(stub->HasSideEffects(isolate()) || !result_type->Is(Type::None()))); |
|
877 |
|
|
878 |
HValue* result = NULL; |
|
879 |
if (stub->operation() == Token::ADD && |
|
880 |
(left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && |
|
881 |
!left_type->Is(Type::String()) && !right_type->Is(Type::String())) { |
|
882 |
// For the generic add stub a fast case for string addition is performance |
|
883 |
// critical. |
|
884 |
if (left_type->Maybe(Type::String())) { |
|
885 |
IfBuilder if_leftisstring(this); |
|
886 |
if_leftisstring.If<HIsStringAndBranch>(left); |
|
887 |
if_leftisstring.Then(); |
|
888 |
{ |
|
889 |
Push(AddInstruction(BuildBinaryOperation( |
|
890 |
stub->operation(), left, right, |
|
891 |
handle(Type::String(), isolate()), right_type, |
|
892 |
result_type, stub->fixed_right_arg(), true))); |
|
893 |
} |
|
894 |
if_leftisstring.Else(); |
|
895 |
{ |
|
896 |
Push(AddInstruction(BuildBinaryOperation( |
|
897 |
stub->operation(), left, right, |
|
898 |
left_type, right_type, result_type, |
|
899 |
stub->fixed_right_arg(), true))); |
|
900 |
} |
|
901 |
if_leftisstring.End(); |
|
902 |
result = Pop(); |
|
903 |
} else { |
|
904 |
IfBuilder if_rightisstring(this); |
|
905 |
if_rightisstring.If<HIsStringAndBranch>(right); |
|
906 |
if_rightisstring.Then(); |
|
907 |
{ |
|
908 |
Push(AddInstruction(BuildBinaryOperation( |
|
909 |
stub->operation(), left, right, |
|
910 |
left_type, handle(Type::String(), isolate()), |
|
911 |
result_type, stub->fixed_right_arg(), true))); |
|
912 |
} |
|
913 |
if_rightisstring.Else(); |
|
914 |
{ |
|
915 |
Push(AddInstruction(BuildBinaryOperation( |
|
916 |
stub->operation(), left, right, |
|
917 |
left_type, right_type, result_type, |
|
918 |
stub->fixed_right_arg(), true))); |
|
919 |
} |
|
920 |
if_rightisstring.End(); |
|
921 |
result = Pop(); |
|
922 |
} |
|
923 |
} else { |
|
924 |
result = AddInstruction(BuildBinaryOperation( |
|
925 |
stub->operation(), left, right, |
|
926 |
left_type, right_type, result_type, |
|
927 |
stub->fixed_right_arg(), true)); |
|
928 |
} |
|
929 |
|
|
930 |
// If we encounter a generic argument, the number conversion is |
|
931 |
// observable, thus we cannot afford to bail out after the fact. |
|
932 |
if (!stub->HasSideEffects(isolate())) { |
|
933 |
if (result_type->Is(Type::Smi())) { |
|
934 |
if (stub->operation() == Token::SHR) { |
|
935 |
// TODO(olivf) Replace this by a SmiTagU Instruction. |
|
936 |
// 0x40000000: this number would convert to negative when interpreting |
|
937 |
// the register as signed value; |
|
938 |
IfBuilder if_of(this); |
|
939 |
if_of.IfNot<HCompareNumericAndBranch>(result, |
|
940 |
Add<HConstant>(static_cast<int>(SmiValuesAre32Bits() |
|
941 |
? 0x80000000 : 0x40000000)), Token::EQ_STRICT); |
|
942 |
if_of.Then(); |
|
943 |
if_of.ElseDeopt("UInt->Smi oveflow"); |
|
944 |
if_of.End(); |
|
945 |
} |
|
946 |
} |
|
947 |
result = EnforceNumberType(result, result_type); |
|
948 |
} |
|
949 |
|
|
950 |
// Reuse the double box of one of the operands if we are allowed to (i.e. |
|
951 |
// chained binops). |
|
952 |
if (stub->CanReuseDoubleBox()) { |
|
953 |
HValue* operand = (stub->mode() == OVERWRITE_LEFT) ? left : right; |
|
954 |
IfBuilder if_heap_number(this); |
|
955 |
if_heap_number.IfNot<HIsSmiAndBranch>(operand); |
|
956 |
if_heap_number.Then(); |
|
957 |
Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result); |
|
958 |
Push(operand); |
|
959 |
if_heap_number.Else(); |
|
960 |
Push(result); |
|
961 |
if_heap_number.End(); |
|
962 |
result = Pop(); |
|
963 |
} |
|
964 |
|
|
965 |
return result; |
|
966 |
} |
|
967 |
|
|
968 |
|
|
969 |
Handle<Code> BinaryOpStub::GenerateCode(Isolate* isolate) { |
|
970 |
return DoGenerateCode(isolate, this); |
|
971 |
} |
|
972 |
|
|
973 |
|
|
974 |
template <> |
|
815 | 975 |
HValue* CodeStubGraphBuilder<ToBooleanStub>::BuildCodeInitializedStub() { |
816 | 976 |
ToBooleanStub* stub = casted_stub(); |
817 | 977 |
|
... | ... | |
918 | 1078 |
HValue* native_context, |
919 | 1079 |
HValue* code_object) { |
920 | 1080 |
Counters* counters = isolate()->counters(); |
921 |
AddIncrementCounter(counters->fast_new_closure_install_optimized(), |
|
922 |
context()); |
|
1081 |
AddIncrementCounter(counters->fast_new_closure_install_optimized()); |
|
923 | 1082 |
|
924 | 1083 |
// TODO(fschneider): Idea: store proper code pointers in the optimized code |
925 | 1084 |
// map and either unmangle them on marking or do nothing as the whole map is |
... | ... | |
967 | 1126 |
} |
968 | 1127 |
is_optimized.Else(); |
969 | 1128 |
{ |
970 |
AddIncrementCounter(counters->fast_new_closure_try_optimized(), context());
|
|
1129 |
AddIncrementCounter(counters->fast_new_closure_try_optimized()); |
|
971 | 1130 |
// optimized_map points to fixed array of 3-element entries |
972 | 1131 |
// (native context, optimized code, literals). |
973 | 1132 |
// Map must never be empty, so check the first elements. |
... | ... | |
1012 | 1171 |
} |
1013 | 1172 |
restore_check.Else(); |
1014 | 1173 |
{ |
1015 |
HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key,
|
|
1016 |
shared_function_entry_length));
|
|
1174 |
HValue* keyed_minus = AddUncasted<HSub>(
|
|
1175 |
key, shared_function_entry_length);
|
|
1017 | 1176 |
HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map, |
1018 | 1177 |
keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1019 | 1178 |
IfBuilder done_check(this); |
... | ... | |
1022 | 1181 |
done_check.Then(); |
1023 | 1182 |
{ |
1024 | 1183 |
// Hit: fetch the optimized code. |
1025 |
HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(),
|
|
1026 |
keyed_minus, graph()->GetConstant1()));
|
|
1184 |
HValue* keyed_plus = AddUncasted<HAdd>(
|
|
1185 |
keyed_minus, graph()->GetConstant1()); |
|
1027 | 1186 |
HValue* code_object = Add<HLoadKeyed>(optimized_map, |
1028 | 1187 |
keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1029 | 1188 |
BuildInstallOptimizedCode(js_function, native_context, code_object); |
... | ... | |
1052 | 1211 |
Add<HConstant>(factory->empty_fixed_array()); |
1053 | 1212 |
HValue* shared_info = GetParameter(0); |
1054 | 1213 |
|
1214 |
AddIncrementCounter(counters->fast_new_closure_total()); |
|
1215 |
|
|
1055 | 1216 |
// Create a new closure from the given function info in new space |
1056 | 1217 |
HValue* size = Add<HConstant>(JSFunction::kSize); |
1057 | 1218 |
HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(), |
1058 | 1219 |
NOT_TENURED, JS_FUNCTION_TYPE); |
1059 |
AddIncrementCounter(counters->fast_new_closure_total(), context()); |
|
1060 | 1220 |
|
1061 | 1221 |
int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(), |
1062 | 1222 |
casted_stub()->is_generator()); |
Also available in: Unified diff