7 #if V8_TARGET_ARCH_MIPS64
16 #define __ ACCESS_MASM(masm)
20 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
21 Handle<JSFunction> getter) {
30 if (!getter.is_null()) {
38 ParameterCount actual(0);
39 ParameterCount expected(getter);
45 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
56 MacroAssembler* masm, Handle<HeapType> type, Register receiver,
57 Handle<JSFunction> setter) {
67 if (!setter.is_null()) {
75 ParameterCount actual(1);
76 ParameterCount expected(setter);
82 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
96 MacroAssembler* masm, Label* miss_label, Register receiver,
97 Handle<Name>
name, Register scratch0, Register scratch1) {
99 DCHECK(!receiver.is(scratch0));
100 Counters* counters = masm->isolate()->counters();
101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
106 const int kInterceptorOrAccessCheckNeededMask =
110 Register
map = scratch1;
113 __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
114 __ Branch(miss_label,
ne, scratch0, Operand(zero_reg));
121 Register properties = scratch0;
125 Register tmp = properties;
126 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
127 __ Branch(miss_label,
ne,
map, Operand(tmp));
134 masm, miss_label, &done, receiver, properties,
name, scratch1);
136 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
141 MacroAssembler* masm,
int index, Register prototype, Label* miss) {
142 Isolate* isolate = masm->isolate();
144 Handle<JSFunction>
function(
145 JSFunction::cast(isolate->native_context()->get(index)));
148 Register scratch = prototype;
154 __ Branch(miss,
ne, at, Operand(scratch));
157 __ li(prototype, Handle<Map>(function->initial_map()));
164 MacroAssembler* masm, Register receiver, Register scratch1,
165 Register scratch2, Label* miss_label) {
166 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
168 __ mov(v0, scratch1);
176 MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name>
name,
177 Register scratch, Label* miss) {
179 DCHECK(cell->value()->IsTheHole());
180 __ li(scratch, Operand(cell));
182 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
183 __ Branch(miss,
ne, scratch, Operand(at));
187 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
188 Register holder, Register
name,
189 Handle<JSObject> holder_obj) {
196 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
197 DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
198 Register scratch =
name;
199 __ li(scratch, Operand(interceptor));
200 __ Push(scratch, receiver, holder);
204 static void CompileCallLoadPropertyWithInterceptor(
205 MacroAssembler* masm, Register receiver, Register holder, Register
name,
207 PushInterceptorArguments(masm, receiver, holder,
name, holder_obj);
208 __ CallExternalReference(ExternalReference(IC_Utility(
id), masm->isolate()),
215 MacroAssembler* masm,
const CallOptimization& optimization,
216 Handle<Map> receiver_map, Register receiver, Register scratch_in,
217 bool is_store,
int argc, Register* values) {
218 DCHECK(!receiver.is(scratch_in));
223 for (
int i = 0;
i < argc;
i++) {
224 Register arg = values[argc - 1 -
i];
225 DCHECK(!receiver.is(arg));
226 DCHECK(!scratch_in.is(arg));
229 DCHECK(optimization.is_simple_api_call());
232 Register callee = a0;
233 Register call_data = a4;
235 Register api_function_address = a1;
238 CallOptimization::HolderLookup holder_lookup;
239 Handle<JSObject> api_holder =
240 optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
241 switch (holder_lookup) {
242 case CallOptimization::kHolderIsReceiver:
245 case CallOptimization::kHolderFound:
248 case CallOptimization::kHolderNotFound:
253 Isolate* isolate = masm->isolate();
254 Handle<JSFunction>
function = optimization.constant_function();
255 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
256 Handle<Object> call_data_obj(api_call_info->data(), isolate);
259 __ li(callee,
function);
261 bool call_data_undefined =
false;
263 if (isolate->heap()->InNewSpace(*call_data_obj)) {
264 __ li(call_data, api_call_info);
266 }
else if (call_data_obj->IsUndefined()) {
267 call_data_undefined =
true;
268 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
270 __ li(call_data, call_data_obj);
273 Address function_address = v8::ToCData<Address>(api_call_info->callback());
274 ApiFunction fun(function_address);
276 ExternalReference ref = ExternalReference(&fun,
type, masm->isolate());
277 __ li(api_function_address, Operand(ref));
280 CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
281 __ TailCallStub(&stub);
292 ExternalReference ref =
293 ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
294 __ TailCallExternalReference(ref, 3, 1);
305 ExternalReference ref =
306 ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
307 __ TailCallExternalReference(ref, 3, 1);
312 #define __ ACCESS_MASM(masm())
317 if (!label->is_unused()) {
328 Handle<Map> transition, Handle<Name>
name, Register receiver_reg,
329 Register storage_reg, Register value_reg, Register scratch1,
330 Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
334 int descriptor = transition->LastAdded();
335 DescriptorArray* descriptors = transition->instance_descriptors();
336 PropertyDetails details = descriptors->GetDetails(descriptor);
337 Representation representation = details.representation();
338 DCHECK(!representation.IsNone());
341 Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
342 __ li(scratch1, constant);
343 __ Branch(miss_label,
ne, value_reg, Operand(scratch1));
344 }
else if (representation.IsSmi()) {
345 __ JumpIfNotSmi(value_reg, miss_label);
346 }
else if (representation.IsHeapObject()) {
347 __ JumpIfSmi(value_reg, miss_label);
348 HeapType* field_type = descriptors->GetFieldType(descriptor);
349 HeapType::Iterator<Map> it = field_type->Classes();
356 current = it.Current();
359 __ Branch(miss_label,
ne, scratch1, Operand(current));
362 __ Branch(&do_store,
eq, scratch1, Operand(current));
366 }
else if (representation.IsDouble()) {
367 Label do_store, heap_number;
368 __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
369 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
372 __ JumpIfNotSmi(value_reg, &heap_number);
373 __ SmiUntag(scratch1, value_reg);
374 __ mtc1(scratch1,
f6);
378 __ bind(&heap_number);
379 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
388 DCHECK(!transition->is_access_check_needed());
391 if (details.type() ==
FIELD &&
392 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
395 __ push(receiver_reg);
396 __ li(a2, Operand(transition));
398 __ TailCallExternalReference(
399 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
406 __ li(scratch1, Operand(transition));
421 int index = transition->instance_descriptors()->GetFieldIndex(
422 transition->LastAdded());
427 index -= transition->inobject_properties();
434 int offset = transition->instance_size() + (index *
kPointerSize);
435 if (representation.IsDouble()) {
441 if (!representation.IsSmi()) {
443 if (!representation.IsDouble()) {
444 __ mov(storage_reg, value_reg);
446 __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
455 if (representation.IsDouble()) {
461 if (!representation.IsSmi()) {
463 if (!representation.IsDouble()) {
464 __ mov(storage_reg, value_reg);
466 __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
483 DCHECK(lookup->representation().IsHeapObject());
484 __ JumpIfSmi(value_reg, miss_label);
485 HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
491 current = it.Current();
494 __ Branch(miss_label,
ne, scratch1(), Operand(current));
497 __ Branch(&do_store,
eq, scratch1(), Operand(current));
501 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
502 lookup->representation());
503 GenerateTailCall(masm(), stub.GetCode());
508 Register object_reg, Register holder_reg, Register scratch1,
509 Register scratch2, Handle<Name>
name, Label* miss,
514 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
515 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
516 !scratch2.is(scratch1));
519 Register reg = object_reg;
523 if (
type()->IsConstant()) {
527 Handle<Map> current_map = receiver_map;
531 while (!current_map.is_identical_to(holder_map)) {
536 DCHECK(current_map->IsJSGlobalProxyMap() ||
537 !current_map->is_access_check_needed());
539 prototype =
handle(JSObject::cast(current_map->prototype()));
540 if (current_map->is_dictionary_map() &&
541 !current_map->IsJSGlobalObjectMap()) {
542 DCHECK(!current_map->IsJSGlobalProxyMap());
543 if (!
name->IsUniqueName()) {
547 DCHECK(current.is_null() ||
548 current->property_dictionary()->FindEntry(
name) ==
562 bool load_prototype_from_map =
563 heap()->InNewSpace(*prototype) || depth == 1;
564 Register map_reg = scratch1;
578 if (current_map->IsJSGlobalProxyMap()) {
579 __ CheckAccessGlobalProxy(reg, scratch2, miss);
580 }
else if (current_map->IsJSGlobalObjectMap()) {
582 name, scratch2, miss);
587 if (load_prototype_from_map) {
590 __ li(reg, Operand(prototype));
596 current_map =
handle(current->map());
600 LOG(isolate(), IntEvent(
"check-maps-depth", depth + 1));
608 DCHECK(current_map->IsJSGlobalProxyMap() ||
609 !current_map->is_access_check_needed());
610 if (current_map->IsJSGlobalProxyMap()) {
611 __ CheckAccessGlobalProxy(reg, scratch1, miss);
620 if (!miss->is_unused()) {
624 TailCallBuiltin(masm(), MissBuiltin(kind()));
631 if (!miss->is_unused()) {
635 TailCallBuiltin(masm(), MissBuiltin(kind()));
649 Register reg, Handle<ExecutableAccessorInfo> callback) {
659 DCHECK(!scratch2().is(reg));
660 DCHECK(!scratch3().is(reg));
663 if (heap()->InNewSpace(callback->data())) {
664 __ li(scratch3(), callback);
668 __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
672 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
675 __ li(
scratch4(), Operand(ExternalReference::isolate_address(isolate())));
681 __ mov(a2, scratch2());
685 Address getter_address = v8::ToCData<Address>(callback->getter());
686 ApiFunction fun(getter_address);
688 ExternalReference ref = ExternalReference(&fun,
type, isolate());
689 __ li(getter_address_reg, Operand(ref));
691 CallApiGetterStub stub(isolate());
692 __ TailCallStub(&stub);
697 LookupIterator* it, Register holder_reg) {
699 DCHECK(!
holder()->GetNamedInterceptor()->getter()->IsUndefined());
704 DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
710 bool must_perform_prototype_check =
711 !
holder().is_identical_to(it->GetHolder<JSObject>());
712 bool must_preserve_receiver_reg =
713 !receiver().is(holder_reg) &&
720 if (must_preserve_receiver_reg) {
721 __ Push(receiver(), holder_reg, this->
name());
728 CompileCallLoadPropertyWithInterceptor(
729 masm(), receiver(), holder_reg, this->
name(),
holder(),
730 IC::kLoadPropertyWithInterceptorOnly);
734 Label interceptor_failed;
735 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
736 __ Branch(&interceptor_failed,
eq, v0, Operand(scratch1()));
737 frame_scope.GenerateLeaveFrame();
740 __ bind(&interceptor_failed);
741 if (must_preserve_receiver_reg) {
742 __ Pop(receiver(), holder_reg, this->
name());
744 __ Pop(holder_reg, this->
name());
756 DCHECK(!
holder()->GetNamedInterceptor()->getter()->IsUndefined());
757 PushInterceptorArguments(masm(), receiver(), holder_reg, this->
name(),
760 ExternalReference ref = ExternalReference(
761 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
762 __ TailCallExternalReference(
768 Handle<JSObject>
object, Handle<Name>
name,
769 Handle<ExecutableAccessorInfo> callback) {
772 __ Push(receiver(), holder_reg);
773 __ li(at, Operand(callback));
779 ExternalReference store_callback_property =
780 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
781 __ TailCallExternalReference(store_callback_property, 5, 1);
793 ExternalReference store_ic_property = ExternalReference(
794 IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
795 __ TailCallExternalReference(store_ic_property, 3, 1);
808 Handle<PropertyCell> cell, Handle<Name>
name,
bool is_configurable) {
815 __ li(result, Operand(cell));
819 if (is_configurable) {
820 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
821 __ Branch(&miss,
eq, result, Operand(at));
824 Counters* counters = isolate()->counters();
825 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
static const Register function_address()
static const int kDataOffset
static const int kValueOffset
static int SlotOffset(int index)
static const int kReturnValueOffset
static void GenerateStoreSlow(MacroAssembler *masm)
static const int kDataOffset
static const int kHeaderSize
static const int kNativeContextOffset
static const int kGlobalProxyOffset
static Handle< T > cast(Handle< S > that)
static Handle< T > null()
static const int kNotFound
static const int kValueOffset
static const int kMapOffset
static Handle< Map > TypeToMap(HeapType *type, Isolate *isolate)
static Handle< PropertyCell > EnsurePropertyCell(Handle< JSGlobalObject > global, Handle< Name > name)
static const int kPropertiesOffset
static const int kBitFieldOffset
static const int kIsAccessCheckNeeded
static const int kInstanceTypeOffset
static const int kHasNamedInterceptor
static const int kPrototypeOffset
static void GenerateNegativeLookup(MacroAssembler *masm, Label *miss, Label *done, Register receiver, Register properties, Handle< Name > name, Register scratch0)
static const int kInterceptorArgsNameIndex
static const int kInterceptorArgsInfoIndex
Handle< Code > CompileLoadGlobal(Handle< PropertyCell > cell, Handle< Name > name, bool is_configurable)
static const int kInterceptorArgsThisIndex
virtual void FrontendFooter(Handle< Name > name, Label *miss)
static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler *masm, int index, Register prototype, Label *miss)
void GenerateLoadInterceptorWithFollowup(LookupIterator *it, Register holder_reg)
virtual Register FrontendHeader(Register object_reg, Handle< Name > name, Label *miss)
static const int kInterceptorArgsHolderIndex
void GenerateLoadConstant(Handle< Object > value)
void GenerateLoadInterceptor(Register holder_reg)
static void GenerateLoadFunctionPrototype(MacroAssembler *masm, Register receiver, Register scratch1, Register scratch2, Label *miss_label)
static const int kInterceptorArgsLength
void GenerateLoadPostInterceptor(LookupIterator *it, Register reg)
static void GenerateLoadViaGetter(MacroAssembler *masm, Handle< HeapType > type, Register receiver, Handle< JSFunction > getter)
void GenerateLoadCallback(Register reg, Handle< ExecutableAccessorInfo > callback)
Handle< Code > CompileStoreInterceptor(Handle< Name > name)
virtual void FrontendFooter(Handle< Name > name, Label *miss)
void GenerateStoreField(LookupIterator *lookup, Register value_reg, Label *miss_label)
Handle< Code > CompileStoreCallback(Handle< JSObject > object, Handle< Name > name, Handle< ExecutableAccessorInfo > callback)
static void GenerateSlow(MacroAssembler *masm)
void GenerateRestoreName(Label *label, Handle< Name > name)
void GenerateStoreTransition(Handle< Map > transition, Handle< Name > name, Register receiver_reg, Register name_reg, Register value_reg, Register scratch1, Register scratch2, Register scratch3, Label *miss_label, Label *slow)
static void GenerateStoreViaSetter(MacroAssembler *masm, Handle< HeapType > type, Register receiver, Handle< JSFunction > setter)
static const int kArgsLength
static const int kHolderIndex
static const int kDataIndex
static const int kIsolateIndex
static const int kThisIndex
static const int kReturnValueDefaultValueIndex
Handle< JSObject > holder() const
Register CheckPrototypes(Register object_reg, Register holder_reg, Register scratch1, Register scratch2, Handle< Name > name, Label *miss, PrototypeCheckType check=CHECK_ALL_MAPS)
Handle< Code > GetCode(Code::Kind kind, Code::StubType type, Handle< Name > name)
Handle< HeapType > type() const
static void GenerateDictionaryNegativeLookup(MacroAssembler *masm, Label *miss_label, Register receiver, Handle< Name > name, Register r0, Register r1)
static void GenerateFastApiCall(MacroAssembler *masm, const CallOptimization &optimization, Handle< Map > receiver_map, Register receiver, Register scratch, bool is_store, int argc, Register *values)
Register Frontend(Register object_reg, Handle< Name > name)
static void GenerateCheckPropertyCell(MacroAssembler *masm, Handle< JSGlobalObject > global, Handle< Name > name, Register scratch, Label *miss)
static const int kContextOffset
static const Register ReceiverRegister()
static const Register NameRegister()
static const Register ValueRegister()
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
#define LOG(isolate, Call)
#define DCHECK(condition)
static int Push(SpecialRPOStackFrame *stack, int depth, BasicBlock *child, int unvisited)
TypeImpl< ZoneTypeConfig > Type
TypeImpl< HeapTypeConfig > HeapType
Handle< T > handle(T *t, Isolate *isolate)
MemOperand FieldMemOperand(Register object, int offset)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
Debugger support for the V8 JavaScript engine.