Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 } 1584 }
1585 1585
1586 1586
1587 void MacroAssembler::Allocate(int object_size, 1587 void MacroAssembler::Allocate(int object_size,
1588 Register result, 1588 Register result,
1589 Register result_end, 1589 Register result_end,
1590 Register scratch, 1590 Register scratch,
1591 Label* gc_required, 1591 Label* gc_required,
1592 AllocationFlags flags) { 1592 AllocationFlags flags) {
1593 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 1593 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
1594 ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize); 1594 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
1595 if (!FLAG_inline_new) { 1595 if (!FLAG_inline_new) {
1596 if (emit_debug_code()) { 1596 if (emit_debug_code()) {
1597 // Trash the registers to simulate an allocation failure. 1597 // Trash the registers to simulate an allocation failure.
1598 mov(result, Immediate(0x7091)); 1598 mov(result, Immediate(0x7091));
1599 if (result_end.is_valid()) { 1599 if (result_end.is_valid()) {
1600 mov(result_end, Immediate(0x7191)); 1600 mov(result_end, Immediate(0x7191));
1601 } 1601 }
1602 if (scratch.is_valid()) { 1602 if (scratch.is_valid()) {
1603 mov(scratch, Immediate(0x7291)); 1603 mov(scratch, Immediate(0x7291));
1604 } 1604 }
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 2290
2291 void MacroAssembler::PrepareCallApiFunction(int argc) { 2291 void MacroAssembler::PrepareCallApiFunction(int argc) {
2292 EnterApiExitFrame(argc); 2292 EnterApiExitFrame(argc);
2293 if (emit_debug_code()) { 2293 if (emit_debug_code()) {
2294 mov(esi, Immediate(BitCast<int32_t>(kZapValue))); 2294 mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
2295 } 2295 }
2296 } 2296 }
2297 2297
2298 2298
2299 void MacroAssembler::CallApiFunctionAndReturn( 2299 void MacroAssembler::CallApiFunctionAndReturn(
2300 Address function_address, 2300 Register function_address,
2301 Address thunk_address, 2301 Address thunk_address,
2302 Operand thunk_last_arg, 2302 Operand thunk_last_arg,
2303 int stack_space, 2303 int stack_space,
2304 Operand return_value_operand, 2304 Operand return_value_operand,
2305 Operand* context_restore_operand) { 2305 Operand* context_restore_operand) {
2306 ExternalReference next_address = 2306 ExternalReference next_address =
2307 ExternalReference::handle_scope_next_address(isolate()); 2307 ExternalReference::handle_scope_next_address(isolate());
2308 ExternalReference limit_address = 2308 ExternalReference limit_address =
2309 ExternalReference::handle_scope_limit_address(isolate()); 2309 ExternalReference::handle_scope_limit_address(isolate());
2310 ExternalReference level_address = 2310 ExternalReference level_address =
2311 ExternalReference::handle_scope_level_address(isolate()); 2311 ExternalReference::handle_scope_level_address(isolate());
2312 2312
2313 ASSERT(edx.is(function_address));
2313 // Allocate HandleScope in callee-save registers. 2314 // Allocate HandleScope in callee-save registers.
2314 mov(ebx, Operand::StaticVariable(next_address)); 2315 mov(ebx, Operand::StaticVariable(next_address));
2315 mov(edi, Operand::StaticVariable(limit_address)); 2316 mov(edi, Operand::StaticVariable(limit_address));
2316 add(Operand::StaticVariable(level_address), Immediate(1)); 2317 add(Operand::StaticVariable(level_address), Immediate(1));
2317 2318
2318 if (FLAG_log_timer_events) { 2319 if (FLAG_log_timer_events) {
2319 FrameScope frame(this, StackFrame::MANUAL); 2320 FrameScope frame(this, StackFrame::MANUAL);
2320 PushSafepointRegisters(); 2321 PushSafepointRegisters();
2321 PrepareCallCFunction(1, eax); 2322 PrepareCallCFunction(1, eax);
2322 mov(Operand(esp, 0), 2323 mov(Operand(esp, 0),
2323 Immediate(ExternalReference::isolate_address(isolate()))); 2324 Immediate(ExternalReference::isolate_address(isolate())));
2324 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 2325 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
2325 PopSafepointRegisters(); 2326 PopSafepointRegisters();
2326 } 2327 }
2327 2328
2328 2329
2329 Label profiler_disabled; 2330 Label profiler_disabled;
2330 Label end_profiler_check; 2331 Label end_profiler_check;
2331 bool* is_profiling_flag = 2332 bool* is_profiling_flag =
2332 isolate()->cpu_profiler()->is_profiling_address(); 2333 isolate()->cpu_profiler()->is_profiling_address();
2333 STATIC_ASSERT(sizeof(*is_profiling_flag) == 1); 2334 STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
2334 mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag))); 2335 mov(eax, Immediate(reinterpret_cast<Address>(is_profiling_flag)));
2335 cmpb(Operand(eax, 0), 0); 2336 cmpb(Operand(eax, 0), 0);
2336 j(zero, &profiler_disabled); 2337 j(zero, &profiler_disabled);
2337 2338
2338 // Additional parameter is the address of the actual getter function. 2339 // Additional parameter is the address of the actual getter function.
2339 mov(thunk_last_arg, Immediate(function_address)); 2340 mov(thunk_last_arg, function_address);
2340 // Call the api function. 2341 // Call the api function.
2341 call(thunk_address, RelocInfo::RUNTIME_ENTRY); 2342 call(thunk_address, RelocInfo::RUNTIME_ENTRY);
2342 jmp(&end_profiler_check); 2343 jmp(&end_profiler_check);
2343 2344
2344 bind(&profiler_disabled); 2345 bind(&profiler_disabled);
2345 // Call the api function. 2346 // Call the api function.
2346 call(function_address, RelocInfo::RUNTIME_ENTRY); 2347 call(function_address);
2347 bind(&end_profiler_check); 2348 bind(&end_profiler_check);
2348 2349
2349 if (FLAG_log_timer_events) { 2350 if (FLAG_log_timer_events) {
2350 FrameScope frame(this, StackFrame::MANUAL); 2351 FrameScope frame(this, StackFrame::MANUAL);
2351 PushSafepointRegisters(); 2352 PushSafepointRegisters();
2352 PrepareCallCFunction(1, eax); 2353 PrepareCallCFunction(1, eax);
2353 mov(Operand(esp, 0), 2354 mov(Operand(esp, 0),
2354 Immediate(ExternalReference::isolate_address(isolate()))); 2355 Immediate(ExternalReference::isolate_address(isolate())));
2355 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 2356 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
2356 PopSafepointRegisters(); 2357 PopSafepointRegisters();
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 cmp(map_in_out, FieldOperand(scratch, offset)); 2682 cmp(map_in_out, FieldOperand(scratch, offset));
2682 j(not_equal, no_map_match); 2683 j(not_equal, no_map_match);
2683 2684
2684 // Use the transitioned cached map. 2685 // Use the transitioned cached map.
2685 offset = transitioned_kind * kPointerSize + 2686 offset = transitioned_kind * kPointerSize +
2686 FixedArrayBase::kHeaderSize; 2687 FixedArrayBase::kHeaderSize;
2687 mov(map_in_out, FieldOperand(scratch, offset)); 2688 mov(map_in_out, FieldOperand(scratch, offset));
2688 } 2689 }
2689 2690
2690 2691
2691 void MacroAssembler::LoadInitialArrayMap(
2692 Register function_in, Register scratch,
2693 Register map_out, bool can_have_holes) {
2694 ASSERT(!function_in.is(map_out));
2695 Label done;
2696 mov(map_out, FieldOperand(function_in,
2697 JSFunction::kPrototypeOrInitialMapOffset));
2698 if (!FLAG_smi_only_arrays) {
2699 ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
2700 LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2701 kind,
2702 map_out,
2703 scratch,
2704 &done);
2705 } else if (can_have_holes) {
2706 LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
2707 FAST_HOLEY_SMI_ELEMENTS,
2708 map_out,
2709 scratch,
2710 &done);
2711 }
2712 bind(&done);
2713 }
2714
2715
2716 void MacroAssembler::LoadGlobalContext(Register global_context) {
2717 // Load the global or builtins object from the current context.
2718 mov(global_context,
2719 Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
2720 // Load the native context from the global or builtins object.
2721 mov(global_context,
2722 FieldOperand(global_context, GlobalObject::kNativeContextOffset));
2723 }
2724
2725
2726 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 2692 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
2727 // Load the global or builtins object from the current context. 2693 // Load the global or builtins object from the current context.
2728 mov(function, 2694 mov(function,
2729 Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2695 Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
2730 // Load the native context from the global or builtins object. 2696 // Load the native context from the global or builtins object.
2731 mov(function, 2697 mov(function,
2732 FieldOperand(function, GlobalObject::kNativeContextOffset)); 2698 FieldOperand(function, GlobalObject::kNativeContextOffset));
2733 // Load the function from the native context. 2699 // Load the function from the native context.
2734 mov(function, Operand(function, Context::SlotOffset(index))); 2700 mov(function, Operand(function, Context::SlotOffset(index)));
2735 } 2701 }
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2972 test(esp, Immediate(frame_alignment_mask)); 2938 test(esp, Immediate(frame_alignment_mask));
2973 j(zero, &alignment_as_expected); 2939 j(zero, &alignment_as_expected);
2974 // Abort if stack is not aligned. 2940 // Abort if stack is not aligned.
2975 int3(); 2941 int3();
2976 bind(&alignment_as_expected); 2942 bind(&alignment_as_expected);
2977 } 2943 }
2978 } 2944 }
2979 2945
2980 2946
2981 void MacroAssembler::Abort(BailoutReason reason) { 2947 void MacroAssembler::Abort(BailoutReason reason) {
2982 // We want to pass the msg string like a smi to avoid GC 2948 #ifdef DEBUG
2983 // problems, however msg is not guaranteed to be aligned
2984 // properly. Instead, we pass an aligned pointer that is
2985 // a proper v8 smi, but also pass the alignment difference
2986 // from the real pointer as a smi.
2987 const char* msg = GetBailoutReason(reason); 2949 const char* msg = GetBailoutReason(reason);
2988 intptr_t p1 = reinterpret_cast<intptr_t>(msg);
2989 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
2990 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
2991 #ifdef DEBUG
2992 if (msg != NULL) { 2950 if (msg != NULL) {
2993 RecordComment("Abort message: "); 2951 RecordComment("Abort message: ");
2994 RecordComment(msg); 2952 RecordComment(msg);
2995 } 2953 }
2996 2954
2997 if (FLAG_trap_on_abort) { 2955 if (FLAG_trap_on_abort) {
2998 int3(); 2956 int3();
2999 return; 2957 return;
3000 } 2958 }
3001 #endif 2959 #endif
3002 2960
3003 push(eax); 2961 push(eax);
3004 push(Immediate(p0)); 2962 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(reason))));
3005 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0))));
3006 // Disable stub call restrictions to always allow calls to abort. 2963 // Disable stub call restrictions to always allow calls to abort.
3007 if (!has_frame_) { 2964 if (!has_frame_) {
3008 // We don't actually want to generate a pile of code for this, so just 2965 // We don't actually want to generate a pile of code for this, so just
3009 // claim there is a stack frame, without generating one. 2966 // claim there is a stack frame, without generating one.
3010 FrameScope scope(this, StackFrame::NONE); 2967 FrameScope scope(this, StackFrame::NONE);
3011 CallRuntime(Runtime::kAbort, 2); 2968 CallRuntime(Runtime::kAbort, 1);
3012 } else { 2969 } else {
3013 CallRuntime(Runtime::kAbort, 2); 2970 CallRuntime(Runtime::kAbort, 1);
3014 } 2971 }
3015 // will not return here 2972 // will not return here
3016 int3(); 2973 int3();
3017 } 2974 }
3018 2975
3019 2976
3020 void MacroAssembler::Throw(BailoutReason reason) { 2977 void MacroAssembler::Throw(BailoutReason reason) {
3021 #ifdef DEBUG 2978 #ifdef DEBUG
3022 const char* msg = GetBailoutReason(reason); 2979 const char* msg = GetBailoutReason(reason);
3023 if (msg != NULL) { 2980 if (msg != NULL) {
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 bind(&succeed); 3172 bind(&succeed);
3216 } 3173 }
3217 3174
3218 3175
3219 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, 3176 void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
3220 Register index, 3177 Register index,
3221 Register value, 3178 Register value,
3222 uint32_t encoding_mask) { 3179 uint32_t encoding_mask) {
3223 Label is_object; 3180 Label is_object;
3224 JumpIfNotSmi(string, &is_object, Label::kNear); 3181 JumpIfNotSmi(string, &is_object, Label::kNear);
3225 Throw(kNonObject); 3182 Abort(kNonObject);
3226 bind(&is_object); 3183 bind(&is_object);
3227 3184
3228 push(value); 3185 push(value);
3229 mov(value, FieldOperand(string, HeapObject::kMapOffset)); 3186 mov(value, FieldOperand(string, HeapObject::kMapOffset));
3230 movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); 3187 movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset));
3231 3188
3232 and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 3189 and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
3233 cmp(value, Immediate(encoding_mask)); 3190 cmp(value, Immediate(encoding_mask));
3234 pop(value); 3191 pop(value);
3235 ThrowIf(not_equal, kUnexpectedStringType); 3192 Check(equal, kUnexpectedStringType);
3236 3193
3237 // The index is assumed to be untagged coming in, tag it to compare with the 3194 // The index is assumed to be untagged coming in, tag it to compare with the
3238 // string length without using a temp register, it is restored at the end of 3195 // string length without using a temp register, it is restored at the end of
3239 // this function. 3196 // this function.
3240 SmiTag(index); 3197 SmiTag(index);
3241 // Can't use overflow here directly, compiler can't seem to disambiguate. 3198 Check(no_overflow, kIndexIsTooLarge);
3242 ThrowIf(NegateCondition(no_overflow), kIndexIsTooLarge);
3243 3199
3244 cmp(index, FieldOperand(string, String::kLengthOffset)); 3200 cmp(index, FieldOperand(string, String::kLengthOffset));
3245 ThrowIf(greater_equal, kIndexIsTooLarge); 3201 Check(less, kIndexIsTooLarge);
3246 3202
3247 cmp(index, Immediate(Smi::FromInt(0))); 3203 cmp(index, Immediate(Smi::FromInt(0)));
3248 ThrowIf(less, kIndexIsNegative); 3204 Check(greater_equal, kIndexIsNegative);
3249 3205
3250 // Restore the index 3206 // Restore the index
3251 SmiUntag(index); 3207 SmiUntag(index);
3252 } 3208 }
3253 3209
3254 3210
3255 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { 3211 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
3256 int frame_alignment = OS::ActivationFrameAlignment(); 3212 int frame_alignment = OS::ActivationFrameAlignment();
3257 if (frame_alignment != 0) { 3213 if (frame_alignment != 0) {
3258 // Make stack end at alignment and make room for num_arguments words 3214 // Make stack end at alignment and make room for num_arguments words
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3578 3534
3579 // For all objects but the receiver, check that the cache is empty. 3535 // For all objects but the receiver, check that the cache is empty.
3580 EnumLength(edx, ebx); 3536 EnumLength(edx, ebx);
3581 cmp(edx, Immediate(Smi::FromInt(0))); 3537 cmp(edx, Immediate(Smi::FromInt(0)));
3582 j(not_equal, call_runtime); 3538 j(not_equal, call_runtime);
3583 3539
3584 bind(&start); 3540 bind(&start);
3585 3541
3586 // Check that there are no elements. Register rcx contains the current JS 3542 // Check that there are no elements. Register rcx contains the current JS
3587 // object we've reached through the prototype chain. 3543 // object we've reached through the prototype chain.
3544 Label no_elements;
3588 mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset)); 3545 mov(ecx, FieldOperand(ecx, JSObject::kElementsOffset));
3589 cmp(ecx, isolate()->factory()->empty_fixed_array()); 3546 cmp(ecx, isolate()->factory()->empty_fixed_array());
3547 j(equal, &no_elements);
3548
3549 // Second chance, the object may be using the empty slow element dictionary.
3550 cmp(ecx, isolate()->factory()->empty_slow_element_dictionary());
3590 j(not_equal, call_runtime); 3551 j(not_equal, call_runtime);
3591 3552
3553 bind(&no_elements);
3592 mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 3554 mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
3593 cmp(ecx, isolate()->factory()->null_value()); 3555 cmp(ecx, isolate()->factory()->null_value());
3594 j(not_equal, &next); 3556 j(not_equal, &next);
3595 } 3557 }
3596 3558
3597 3559
3598 void MacroAssembler::TestJSArrayForAllocationMemento( 3560 void MacroAssembler::TestJSArrayForAllocationMemento(
3599 Register receiver_reg, 3561 Register receiver_reg,
3600 Register scratch_reg, 3562 Register scratch_reg,
3601 Label* no_memento_found) { 3563 Label* no_memento_found) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 cmp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 3599 cmp(scratch1, Immediate(DICTIONARY_ELEMENTS));
3638 j(equal, found); 3600 j(equal, found);
3639 mov(current, FieldOperand(current, Map::kPrototypeOffset)); 3601 mov(current, FieldOperand(current, Map::kPrototypeOffset));
3640 cmp(current, Immediate(factory->null_value())); 3602 cmp(current, Immediate(factory->null_value()));
3641 j(not_equal, &loop_again); 3603 j(not_equal, &loop_again);
3642 } 3604 }
3643 3605
3644 } } // namespace v8::internal 3606 } } // namespace v8::internal
3645 3607
3646 #endif // V8_TARGET_ARCH_IA32 3608 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698