From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Martin Pohlack Newsgroups: gmane.emacs.devel Subject: Re: extremely slow font-lock-mode Date: Wed, 12 Dec 2007 01:21:21 +0100 Message-ID: <475F2981.6030108@os.inf.tu-dresden.de> References: <475E659F.4000303@os.inf.tu-dresden.de> <475F0FE3.7000802@gmx.at> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040906060706040305090906" X-Trace: ger.gmane.org 1197432260 24021 80.91.229.12 (12 Dec 2007 04:04:20 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 12 Dec 2007 04:04:20 +0000 (UTC) Cc: martin rudalics To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Dec 12 05:04:30 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1J2Iph-00053W-0a for ged-emacs-devel@m.gmane.org; Wed, 12 Dec 2007 05:04:30 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1J2IpO-0001GG-Eh for ged-emacs-devel@m.gmane.org; Tue, 11 Dec 2007 23:04:10 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1J2FLf-0007m6-0O for emacs-devel@gnu.org; Tue, 11 Dec 2007 19:21:15 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1J2FLd-0007lK-Gh for emacs-devel@gnu.org; Tue, 11 Dec 2007 19:21:14 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1J2FLd-0007lD-92 for emacs-devel@gnu.org; Tue, 11 Dec 2007 19:21:13 -0500 Original-Received: from os.inf.tu-dresden.de ([141.76.48.99]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1J2FLa-0002Kk-Vd for emacs-devel@gnu.org; Tue, 11 Dec 2007 19:21:13 -0500 Original-Received: from pd9eb4964.dip.t-dialin.net ([217.235.73.100] helo=[192.168.1.101]) by os.inf.tu-dresden.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.68) id 1J2FLT-0007Wn-Ro; Wed, 12 Dec 2007 01:21:05 +0100 User-Agent: Thunderbird 2.0.0.9 (X11/20071115) In-Reply-To: <475F0FE3.7000802@gmx.at> X-Enigmail-Version: 0.95.5 X-detected-kernel: by monty-python.gnu.org: Linux 2.6, seldom 2.4 (older, 4) X-Mailman-Approved-At: Tue, 11 Dec 2007 23:04:05 -0500 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:85080 Archived-At: This is a multi-part message in MIME format. --------------040906060706040305090906 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit martin rudalics wrote: >> I'm experiencing very slow syntax highlighting with emacs-23.0.60 >> (GTK+ Version 2.12.1)a. >> >> Simply scrolling in source files takes incredibly long (~ 1 second for >> scolling one line backwards). This is an a dual-core 2 GHZ machine >> ... >> I tried to play with all font-lock and jit-lock customization options >> but only turning font-lock off seemed to make a difference. >> >> I tried to use elp to instrument relevant packages (mwheel, font-lock, >> jit-lock, mouse, lazy-lock, fast-lock). After some scrolling (~ 20 >> seconds, with pauses, mouse wheel, pg-keys and scrollbar) I get >> the following results: > > I suppose you did not turn on lazy-lock or fast-lock, hence these two > are hardly relevant here. No, I did it just for completeness reasons. [...] >> I also noticed, that scrolling forward seems to go considerably faster >> than scrolling backwards (maybe this has to do with syntax-driven >> jit-lock?). > > Usually it's slower only if you scroll back into _not yet fontified_ > areas. That is what I thought too, but I scrolled through the whole file several times before that. Maybe caching the font properties is broken? >> The results are twofold for me: >> >> First, I don't seem to be using elp right or it is the wrong tool. > > You did use it right but it's probably not the right tool for finding > the cause of the problem. Ok, I tried some oprofiling, which of course can only catch native functions. The result is still interesting: $ opreport -l image:/usr/bin/emacs-23-unicode Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit \ mask of 0x00 (Unhalted core cycles) count 240000 samples % symbol name 48798 32.2244 lookup_char_property 37434 24.7200 next_interval 24605 16.2482 get_property_and_range 12083 7.9792 previous_interval 10370 6.8480 Fcdr 9619 6.3520 Fcar 6904 4.5591 textget 355 0.2344 assq_no_quit 170 0.1123 find_interval ... >> Ideally, I would like to use a /sampling/ profiler for emacs. >> - Is there such a thing that can look into running lisp code? >> - How should I be using elp differently for getting meaningful >> results? >> >> Second, font-lock-mode is currently unusable for me. I started emacs >> with -q, so I don't think my local tweak are to blame. emacs-22 on my >> local machine is incredibly fast for the same file (also started with >> -q). >> - What might be to blame here? > > First of all we have to find out whether this is mode specific. > Often a badly constructed regexp can cause such problems. Did you > try with different major modes? Probably not. I see this in tex, c++, c, diff, asm, and text mode. Basically everywhere with larger files. File size seems to matter, also direction of scrolling and position in the file. Also cursor placement using the mouse (no scrolling involved, just clicking somewhere in the visible buffer area) incurs large delays (~ 1 second). > Next you should try if it's buffer specific. I have many source-code files here, which behave similar. I attached two. > Can you post the file showing the bug (maybe it's only a small part of > the file that exhibits the problem). Seems to be everywhere in the files. > >> - Do you need more details on any aspect of my machine configuration? > > Please send these details just as if you reported a bug. I also tried with the current CVS version for the same branch and built it myself with similar results. The output below is from calling report-emacs-bug in the buffer of one such problematic file. In GNU Emacs 23.0.60.1 (i686-pc-linux-gnu, GTK+ Version 2.12.1) of 2007-12-11 on monat Windowing system distributor `The X.Org Foundation', version 11.0.10300000 configured using `configure '--prefix=/usr' '--host=i686-pc-linux-gnu' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--datadir=/usr/share' '--sysconfdir=/etc' '--localstatedir=/var/lib' '--program-suffix=-emacs-23-unicode' '--infodir=/usr/share/info/emacs-23-unicode' '--without-carbon' '--with-sound' '--with-x' '--with-toolkit-scroll-bars' '--enable-font-backend' '--with-freetype' '--with-xft' '--with-jpeg' '--with-tiff' '--with-gif' '--with-png' '--with-xpm' '--with-rsvg' '--with-x-toolkit=gtk' '--without-hesiod' '--with-kerberos' '--with-kerberos5' '--without-gpm' '--build=i686-pc-linux-gnu' 'build_alias=i686-pc-linux-gnu' 'host_alias=i686-pc-linux-gnu' 'CFLAGS=-march=prescott -pipe -O2'' Important settings: value of $LC_ALL: nil value of $LC_COLLATE: POSIX value of $LC_CTYPE: de_DE.UTF-8 value of $LC_MESSAGES: en_US.UTF-8 value of $LC_MONETARY: de_DE.UTF-8 value of $LC_NUMERIC: nil value of $LC_TIME: de_DE.UTF-8 value of $LANG: en_US.UTF-8 value of $XMODIFIERS: nil locale-coding-system: utf-8-unix default-enable-multibyte-characters: t Major mode: C/l Minor modes in effect: shell-dirtrack-mode: t flyspell-mode: t desktop-save-mode: t pc-selection+-mode: t show-paren-mode: t pc-selection-mode: t mouse-sel-mode: t tooltip-mode: t mouse-wheel-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t global-auto-composition-mode: t auto-composition-mode: t auto-compression-mode: t column-number-mode: t line-number-mode: t transient-mark-mode: t abbrev-mode: t --------------040906060706040305090906 Content-Type: text/plain; name="entry-ia32-ux.S" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="entry-ia32-ux.S" /* * This file contains a 'gate_init' initialization table * to initialize the x86 processor trap vectors to default entrypoints. * These entrypoints simply push a standard trap_state frame * and jump to the 'trap_handler' routine. */ #include "config_tcbsize.h" #include "config_gdt.h" #include "globalconfig.h" #include "idt_init.h" #include "low_level.h" #include "shortcut.h" #include "tcboffset.h" #include "asm.h" /* We make the trap handler an interrupt gate, because for debugging purposes, we don't want any interrupts to occur until they're explicitly enabled in the base_trap_handler (usually Thread::handle_slow_trap). */ /* * No error code. Clear error code and push trap number. */ #define EXCEPTION(n,name) \ GATE_ENTRY(n,entry_##name,ACC_PL_K | ACC_INTR_GATE) ;\ .p2align 3 ;\ entry_##name: ;\ pushl $(0) ;\ pushl $(n) ;\ pusha ;\ jmp _slowtraps /* * User-accessible exception. Otherwise, same as above. */ #define EXCEP_USR(n,name) \ GATE_ENTRY(n,entry_##name,ACC_PL_U | ACC_INTR_GATE) ;\ .p2align 3 ;\ entry_##name: ;\ pushl $(0) ;\ pushl $(n) ;\ pusha ;\ jmp _slowtraps /* * Error code has been pushed. Just push trap number. */ #define EXCEP_ERR(n,name) \ GATE_ENTRY(n,entry_##name,ACC_PL_K | ACC_INTR_GATE) ;\ .p2align 3 ;\ entry_##name: ;\ pushl $(n) ;\ pusha ;\ jmp _slowtraps .macro PRE_ALIEN_IPC btrl $17, KSEG OFS__THREAD__STATE (%ebx) /* Thread_dis_alien */ jc 1f RESTORE_STATE sub $2, 4(%esp) /* Correct EIP to point to insn */ popl %eax pushl $(0x30 << 3 | 2) pushl $(0xd) pusha jmp _slowtraps 1: /* do alien IPC and raise a trap afterwards */ RESET_THREAD_CANCEL_AT %ebx .endm .macro POST_ALIEN_IPC CHECK_SANITY $3 /* scratches ecx */ RESET_USER_SEGMENTS $3,in_cli /* scratches ecx */ RESTORE_STATE_AFTER_IPC popl %eax pushl $(0x30 << 3 | 6) pushl $(0xd) pusha jmp _slowtraps .endm #ifdef CONFIG_KERN_LIB_PAGE .macro ROLLBACK_IP addr /* scratches flags * requires address argument as macro parameter */ cmpl $VAL__MEM_LAYOUT__KERN_LIB_BASE,\addr jl 1f cmpl $VAL__MEM_LAYOUT__KERN_LIB_END,\addr jge 1f andl $0xFFFFFFC0,\addr /* roll back eip (64 bytes) */ #if defined(CONFIG_JDB_ACCOUNTING) /* update counter Kern_cnt_lib_page_hit */ incl VAL__MEM_LAYOUT__TBUF_STATUS_PAGE + \ OFS__TBUF_STATUS__KERNCNTS + 44 #endif 1: .endm #endif /* fixme: we could merge the comparisons to speedup the common case */ #ifdef CONFIG_ROLLFORWARD .macro ROLLFORWARD_IP addr /* scratches flags * requires address argument as macro parameter */ // fixme: opcode likely jump cmpl $VAL__MEM_LAYOUT__ROLLFORWARD_BASE,\addr jl 1f // fixme: opcode likely jump cmpl $VAL__MEM_LAYOUT__ROLLFORWARD_END,\addr jge 1f orl $0x1000,\addr /* add 4k to IP by OR, addr must be 8K aligned */ //movl $0x01,$VAL__CONTEXT_RF_ACTIVE // fixme: real address 1: .endm .macro ROLLFORWARD_PANIC addr reason // fixme: opcode likely jump cmpl $VAL__MEM_LAYOUT__ROLLFORWARD_BASE,\addr jl 1f // fixme: opcode likely jump cmpl $VAL__MEM_LAYOUT__ROLLFORWARD_END,\addr jge 1f movl \reason,%eax call rollforward_panic 1: .endm #endif GATE_INITTAB_BEGIN(idt_init_table) EXCEPTION(0x00,vec00_zero_div) #ifdef CONFIG_PF_UX EXCEPTION(0x01,vec01_debug) #else /* IA32 has to handle breakpoint exceptions if occured exactly at entry_sys_fast_ipc -- see ia32/entry-ia32.S */ GATE_ENTRY(0x01,entry_vec01_debug,ACC_PL_K | ACC_INTR_GATE) #endif /* XXX IA32 has to handle NMI occured exactly at entry_sys_fast_ipc */ EXCEP_USR(0x02,vec02_nmi) EXCEP_USR(0x03,vec03_breakpoint) EXCEP_USR(0x04,vec04_into) EXCEP_USR(0x05,vec05_bounds) EXCEPTION(0x06,vec06_invop) /* EXCEPTION(0x07,nofpu) */ #ifdef CONFIG_PF_UX EXCEP_ERR(0x08,vec08_dbl_fault) #else GATE_ENTRY(0x08, GDT_TSS_DBF, ACC_PL_K | ACC_TASK_GATE) #endif EXCEPTION(0x09,vec09_fpu_ovfl) /* EXCEP_ERR(0x0a,vec0a_inv_tss) */ EXCEP_ERR(0x0b,vec0b_segnp) EXCEP_ERR(0x0c,vec0c_stack_fault) EXCEP_ERR(0x0d,vec0d_gen_prot) /* EXCEP_ERR(0x0e,vec0e_page_fault) */ /* EXCEPTION(0x0f,vec0f_trap_0f) */ EXCEPTION(0x10,vec10_fpu_err) EXCEP_ERR(0x11,vec11_align) EXCEPTION(0x12,vec12_mcheck) EXCEPTION(0x13,vec13_simd_err) .p2align 4 .type slowtraps,@function .globl slowtraps /* We have to introduce the label _slowtraps besides the label slowtraps to achive that jmps from exception entry points are optimized to two-byte jmps. The label slowtraps is visible from outside. */ _slowtraps: slowtraps: #ifdef CONFIG_PF_UX # define REG_GS CPU_GS #else # define REG_GS %gs #endif pushl %fs /* we save the segment regs in the trap */ pushl REG_GS /* state, but we do not restore them. We */ pushl %ds /* rather reload them using */ pushl %es /* RESET_{KERNEL,USER}_SEGMENTS */ /* Load the kernel's segment registers. */ RESET_KERNEL_SEGMENTS_FORCE_DS_ES /* scratches ecx, edx */ #ifdef CONFIG_KERN_LIB_PAGE ROLLBACK_IP 56(%esp) // fixme: address correct? (-> trap_state.cpp) #endif #ifdef CONFIG_ROLLFORWARD ROLLFORWARD_PANIC 56(%esp), $0 #endif /* Note: we do not use RESET_THREAD_CANCEL_* here as that is needed only when an I/O-page-fault IPC is sent and when the thread is killed. Resetting Thread_cancel here could be harmful when using this trap handler in debugging. Instead, we clear this flag in Thread::handle_slow_trap() just before sending the IPC message or before killing the thread. That's OK, because it is still atomic -- we never enable IRQs (sti) before that point. */ movl %esp,%eax /* ARG1: address of trap_state */ #ifndef CONFIG_NO_FRAME_PTR pushl 56(%esp) /* create artificial stack frame */ pushl %ebp # ifndef CONFIG_PROFILE leal (%esp),%ebp # else xorl %ebp,%ebp # endif #endif /* Call the C handler function if one has been installed. */ movl BASE_TRAP_HANDLER, %ecx orl %ecx,%ecx jz unexpected_trap_pop call *%ecx in_slowtrap: #ifndef CONFIG_NO_FRAME_PTR leal 8(%esp),%esp #endif /* If the handler function returned zero (success), then resume execution as if the trap never happened. Otherwise, just panic. */ orl %eax,%eax jnz unexpected_trap CHECK_SANITY 60(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 60(%esp),in_cli /* scratches ecx */ addl $4*2,%esp /* Pop ds, es segment registers */ popl REG_GS popl %fs /* Restore segment registers */ popa addl $4*2,%esp /* Pop trap number and error code */ iret unexpected_trap_pop: #ifndef CONFIG_NO_FRAME_PTR leal 8(%esp), %esp #endif unexpected_trap: movw %ss,%ax movw %ax,%ds movw %ax,%es movl %esp,%eax call trap_dump_panic GATE_ENTRY(0x0e,entry_vec0e_page_fault,ACC_PL_K | ACC_INTR_GATE) /* we must save %cr2 before we can be preempted -- therefore we're an interrupt gate (invoked with interrupts turned off). Also, we don't turn them on again here, but only after checking for page-ins from the global page directory in thread_page_fault(). XXX: If you make changes to stack layout here, fix thread_page_fault */ /* XXX slow version - sets up nice stack frame for debugger */ .p2align 4 .type entry_vec0e_page_fault,@function entry_vec0e_page_fault: pushl %eax /* save regs modifiable by C funcs */ pushl %ecx pushl %edx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ movl 12(%esp),%edx /* save error code in ARG2 ... */ movl PAGE_FAULT_ADDR,%eax /* save page fault address in ARG1 */ /* We must reset the cancel flag here atomically if we are entering fresh from user mode and an IPC might occur. NOTE: We cannot test the user-mode bit in the error code because it will flag "kernel" in case an I/O-bitmap page is not mapped during an I/O access. */ movl 20(%esp),%ecx /* get CS from stack */ andb $3,%cl /* retrieve current privilege level (CPL) */ jz 1f /* CPL == 0 -> kernel, skip resetting state */ ESP_TO_TCB_AT %ecx RESET_THREAD_CANCEL_AT %ecx 1: movl %ebp,12(%esp) /* save frame pointer */ leal 12(%esp),%ebp /* load new frame pointer */ #ifdef CONFIG_PROFILE call mcount #endif pushl %eax /* save pf address */ pushl %edx /* save error code */ leal 24(%esp),%ecx /* ARG5: ptr to Return_frame */ pushl %ecx pushl 36(%esp) /* ARG4: eflags */ #ifdef CONFIG_KERN_LIB_PAGE ROLLBACK_IP 32(%esp) #endif #ifdef CONFIG_ROLLFORWARD ROLLFORWARD_PANIC 32(%esp), $1 #endif movl 32(%esp),%ecx /* ARG3: eip */ call thread_page_fault in_page_fault: #ifdef CONFIG_SMALL_SPACES movl 32(%esp),%ecx /* check if page fault was in */ andl $0xFFFFFF00,%ecx /* sysexit trampoline page */ cmpl $VAL__MEM_LAYOUT__SMAS_TRAMPOLINE,%ecx jz page_fault_in_trampoline before_iret_page_fault: #endif orl %eax,%eax jz bad_page_fault lea 16(%esp),%esp CHECK_SANITY 20(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 20(%esp),no_cli /* scratches ecx */ popl %edx popl %ecx popl %eax popl %ebp iret /* If code or stack from a small address space are not yet mapped in the current page directory we might get a page fault on return from the trampoline page. In this case we cannot return to the trampoline page after handling the fault because we are already in user mode (with segment limits below kernel space) while the trampoline code is located in kernel data space. So instead we change ESP and EIP to point to the address the trampoline wanted to return to and do the normal IRET. */ #ifdef CONFIG_SMALL_SPACES page_fault_in_trampoline: /* don't interrupt us here */ cli /* make sure that we use the user-level segment for accessing the user-level eip */ movw $(GDT_DATA_USER|SEL_PL_U), %cx movl %ecx,%ds movl 44(%esp),%ecx /* user esp */ movl (%ecx),%edx movl %edx,32(%esp) addl $16,%ecx movl %ecx,44(%esp) orl %eax,%eax jz bad_page_fault leal 16(%esp),%esp CHECK_SANITY 20(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 20(%esp),in_cli /* scratches ecx */ popl %edx popl %ecx popl %eax popl %ebp iret #endif /* recover from a bad page fault by invoking the slow_trap handler */ .p2align 4 bad_page_fault: cli addl $8,%esp /* pop ARG4 and ARG5 */ movl (%ebp),%eax /* old ebp */ popl (%ebp) /* error code */ popl %edx /* page fault address */ movl %eax,%ebp /* we have on stack: error code, eax, ecx, edx move registers down to make room for trap number */ subl $4,%esp movl 4(%esp),%eax movl %eax,(%esp) movl 8(%esp),%eax movl %eax,4(%esp) movl 12(%esp),%eax movl %eax,8(%esp) movl $0x0e,12(%esp) /* error code */ pushl %ebx /* rest of trap state */ pushl %edx /* page fault address */ pushl %ebp pushl %esi pushl %edi jmp slowtraps /* FPU not available in this context. */ GATE_ENTRY(0x07,entry_vec07_fpu_unavail, ACC_PL_K | ACC_INTR_GATE) /* do all of this with disabled interrupts */ .p2align 4 .type entry_vec07_fpu_unavail,@function entry_vec07_fpu_unavail: pushl %eax pushl %ecx pushl %edx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ call thread_handle_fputrap in_handle_fputrap: CHECK_SANITY 16(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 16(%esp),in_cli /* scratches ecx */ test %eax, %eax jz real_fpu_exception popl %edx popl %ecx popl %eax iret real_fpu_exception: popl %edx popl %ecx popl %eax pushl $(0) pushl $(7) pusha jmp _slowtraps /* timer interrupt */ #ifdef CONFIG_SCHED_PIT GATE_ENTRY(0x20,entry_int_timer,ACC_PL_K | ACC_INTR_GATE) #endif #ifdef CONFIG_SCHED_RTC GATE_ENTRY(0x28,entry_int_timer,ACC_PL_K | ACC_INTR_GATE) #endif #ifdef CONFIG_SCHED_APIC GATE_ENTRY(0x3d,entry_int_timer,ACC_PL_K | ACC_INTR_GATE) #endif .p2align 4 .globl entry_int_timer entry_int_timer: #ifdef CONFIG_KERN_LIB_PAGE ROLLBACK_IP 0(%esp) #endif #ifdef CONFIG_ROLLFORWARD ROLLFORWARD_IP 0(%esp) #endif #ifndef CONFIG_NO_FRAME_PTR pushl %ebp #ifndef CONFIG_PROFILE movl %esp,%ebp #else xorl %ebp,%ebp #endif #endif pushl %eax pushl %edx pushl %ecx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ do_timer_interrupt: #ifdef CONFIG_NO_FRAME_PTR movl 12(%esp), %eax /* ARG1: eip for logging */ #else movl 16(%esp), %eax /* ARG1: eip for logging */ #endif call thread_timer_interrupt /* enter with disabled irqs */ in_timer_interrupt: #ifndef CONFIG_NO_FRAME_PTR CHECK_SANITY 20(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 20(%esp),in_cli /* scratches ecx */ #else CHECK_SANITY 16(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 16(%esp),in_cli /* scratches ecx */ #endif popl %ecx popl %edx popl %eax #ifndef CONFIG_NO_FRAME_PTR popl %ebp #endif iret .p2align 4 .globl entry_int_timer_slow entry_int_timer_slow: #ifdef CONFIG_KERN_LIB_PAGE ROLLBACK_IP 0(%esp) #endif #ifdef CONFIG_ROLLFORWARD ROLLFORWARD_IP 0(%esp) #endif #ifndef CONFIG_NO_FRAME_PTR pushl %ebp #ifndef CONFIG_PROFILE movl %esp,%ebp #else xorl %ebp,%ebp #endif #endif pushl %eax pushl %edx pushl %ecx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ call thread_timer_interrupt_slow /* enter with disabled irqs */ in_timer_interrupt_slow: jmp do_timer_interrupt .p2align 4 .globl entry_int_timer_stop entry_int_timer_stop: #ifndef CONFIG_NO_FRAME_PTR pushl %ebp #ifndef CONFIG_PROFILE movl %esp,%ebp #else xorl %ebp,%ebp #endif #endif pushl %eax pushl %edx pushl %ecx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ call thread_timer_interrupt_stop #ifndef CONFIG_NO_FRAME_PTR CHECK_SANITY 20(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 20(%esp),in_cli /* scratches ecx */ #else CHECK_SANITY 16(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 16(%esp),in_cli /* scratches ecx */ #endif popl %ecx popl %edx popl %eax #ifndef CONFIG_NO_FRAME_PTR popl %ebp #endif iret /* profiling timer interrupt entry point */ #ifdef CONFIG_PROFILE .p2align 4 .globl profile_interrupt_entry .type profile_interrupt_entry,@function profile_interrupt_entry: #ifndef CONFIG_NO_FRAME_PTR pushl %ebp movl %esp,%ebp pushl %eax movl 8(%esp),%eax /* %eax = return address */ #else pushl %eax movl 4(%esp),%eax /* %eax = return address */ #endif pushl %edx pushl %ecx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ call profile_interrupt /* enter with disabled irqs */ #ifndef CONFIG_NO_FRAME_PTR CHECK_SANITY 20(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 20(%esp),in_cli /* scratches ecx */ #else CHECK_SANITY 16(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 16(%esp),in_cli /* scratches ecx */ #endif popl %ecx popl %edx popl %eax #ifndef CONFIG_NO_FRAME_PTR popl %ebp #endif iret #endif /* CONFIG_PROFILE */ /* other interrupts */ #define INTERRUPT(int,name) \ GATE_ENTRY(int,entry_##name,ACC_PL_K | ACC_INTR_GATE) ;\ .p2align 3 ;\ entry_##name: ;\ pushl %eax ;\ movl $ (int - 0x20), %eax /* ARG1: irqnum */ ;\ jmp all_irqs #ifndef CONFIG_SCHED_PIT INTERRUPT(0x20,int0) #endif INTERRUPT(0x21,int1) INTERRUPT(0x22,int2) INTERRUPT(0x23,int3) INTERRUPT(0x24,int4) INTERRUPT(0x25,int5) INTERRUPT(0x26,int6) INTERRUPT(0x27,int7) #ifndef CONFIG_SCHED_RTC INTERRUPT(0x28,int8) #endif INTERRUPT(0x29,int9) INTERRUPT(0x2a,inta) INTERRUPT(0x2b,intb) INTERRUPT(0x2c,intc) INTERRUPT(0x2d,intd) INTERRUPT(0x2e,inte) INTERRUPT(0x2f,intf) .p2align 4 .type all_irqs,@function all_irqs: pushl %edx pushl %ecx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ #ifdef CONFIG_KERN_LIB_PAGE ROLLBACK_IP 12(%esp) #endif #ifdef CONFIG_ROLLFORWARD ROLLFORWARD_IP 12(%esp) #endif movl 12(%esp), %edx /* ARG2: eip */ call irq_interrupt /* enter with disabled irqs */ in_interrupt: CHECK_SANITY 16(%esp) /* scratches ecx */ RESET_USER_SEGMENTS 16(%esp),in_cli /* scratches ecx */ popl %ecx popl %edx popl %eax entry_int_pic_ignore: iret .global entry_int_pic_ignore .global entry_int7 .global entry_intf /****************************************************************************/ /* system calls */ /****************************************************************************/ #ifdef CONFIG_ASSEMBLER_IPC_SHORTCUT GATE_ENTRY(0x30,entry_sys_ipc,ACC_PL_U | ACC_INTR_GATE); #else GATE_ENTRY(0x30,entry_sys_ipc_c,ACC_PL_U | ACC_INTR_GATE); #endif #if defined (CONFIG_JDB_LOGGING) || !defined(CONFIG_ASSEMBLER_IPC_SHORTCUT) .p2align 4 .globl entry_sys_ipc_c entry_sys_ipc_c: pushl %eax SAVE_STATE ESP_TO_TCB_AT %ebx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ testl $Thread_alien, KSEG OFS__THREAD__STATE (%ebx) jnz alien_sys_ipc_c RESET_THREAD_CANCEL_AT %ebx call ipc_short_cut_wrapper in_sc_ipc1: CHECK_SANITY $3 /* scratches ecx */ RESET_USER_SEGMENTS $3,in_cli /* scratches ecx */ RESTORE_STATE_AFTER_IPC popl %eax iret .globl in_sc_ipc1 #endif #ifdef CONFIG_JDB /* The slow variant of sys_ipc_entry is used when logging IPC */ .p2align 4 .globl entry_sys_ipc_log entry_sys_ipc_log: pushl %eax SAVE_STATE ESP_TO_TCB_AT %ebx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ testl $Thread_alien, KSEG OFS__THREAD__STATE (%ebx) jnz alien_sys_ipc_log RESET_THREAD_CANCEL_AT %ebx call *syscall_table in_slow_ipc4: CHECK_SANITY $3 /* scratches ecx */ RESET_USER_SEGMENTS $3,in_cli /* scratches ecx */ RESTORE_STATE_AFTER_IPC popl %eax iret .globl in_slow_ipc4 #endif // CONFIG_JDB // these labels help show_tcb to guess the thread state .globl in_syscall .globl in_slowtrap .globl in_page_fault .globl in_handle_fputrap .globl in_interrupt .globl in_timer_interrupt .globl in_timer_interrupt_slow #define SYSTEM_CALL(int,name) \ GATE_ENTRY(int,entry_##name,ACC_PL_U | ACC_INTR_GATE) ;\ .p2align 3 ;\ entry_##name: ;\ pushl %eax ;\ movl $(syscall_table+4*(int-0x30)), %eax ;\ jmp all_syscalls .p2align 4 .type all_syscalls,@function all_syscalls: SAVE_STATE ;\ ESP_TO_TCB_AT %ebx RESET_KERNEL_SEGMENTS /* scratches ecx, edx */ testl $Thread_alien, KSEG OFS__THREAD__STATE (%ebx) jnz alien_sys_call RESET_THREAD_CANCEL_AT %ebx call *(%eax) /* interrupts enabled in wrappers */ in_syscall: ret_from_syscall: CHECK_SANITY $3 /* scratches ecx */ RESET_USER_SEGMENTS $3,no_cli /* scratches ecx */ RESTORE_STATE popl %eax iret /* SYSTEM_CALL(0x30,sys_ipc) */ SYSTEM_CALL(0x31,sys_id_nearest) SYSTEM_CALL(0x32,sys_fpage_unmap) SYSTEM_CALL(0x33,sys_thread_switch) SYSTEM_CALL(0x34,sys_thread_schedule) SYSTEM_CALL(0x35,sys_thread_ex_regs) SYSTEM_CALL(0x36,sys_task_new) SYSTEM_CALL(0x39,sys_u_lock) #ifdef CONFIG_PL0_HACK SYSTEM_CALL(0x37,sys_priv_control) GATE_ENTRY(0x38,entry_sys_priv_entry,ACC_PL_U | ACC_INTR_GATE) .p2align 3 entry_sys_priv_entry: pushl $0 pushf pushl %eax pushl %edx pushl %ecx lea 16(%esp), %eax call sys_priv_entry_wrapper orl %eax, %eax jz 1f /* restore registers, diverge to user function */ popl %ecx popl %edx popl %eax popfl addl $4, %esp /* Accessing stack beneath the stack pointer is allowed here since we * are executed with interrupts off and we don't expect any exception * as well. */ jmp *-4(%esp) 1: /* no privileges so just return to the user */ addl $20, %esp iret #endif #ifndef CONFIG_PF_UX /* these functions are implemented in entry-ia32.S */ GATE_ENTRY(0x0a,entry_vec0a_invalid_tss,ACC_PL_K | ACC_INTR_GATE) GATE_ENTRY(0x0f,entry_vec0f_apic_spurious_interrupt_bug,ACC_PL_K | ACC_INTR_GATE) GATE_ENTRY(0x3e,entry_vec3e_apic_error_interrupt,ACC_PL_K | ACC_INTR_GATE) GATE_ENTRY(0x3f,entry_vec3f_apic_spurious_interrupt,ACC_PL_K | ACC_INTR_GATE) #endif GATE_INITTAB_END .globl alien_sys_ipc_c /* Also used in shortcut */ alien_sys_ipc_c: PRE_ALIEN_IPC call ipc_short_cut_wrapper POST_ALIEN_IPC #if defined (CONFIG_JDB) alien_sys_ipc_log: PRE_ALIEN_IPC call *syscall_table POST_ALIEN_IPC #endif /* * input: eax: address to syscall function * output: eax: error code */ .macro SC_ADDR_TO_ERR val sub $syscall_table , %eax /* eax = byte offset to syscall */ shr $2, %eax /* convert eax to syscall nr */ add $0x30, %eax /* convert eax to syscall int nr */ shl $3, %eax /* construct error code */ orl $\val, %eax /* -"- */ .endm alien_sys_call: btrl $17, KSEG OFS__THREAD__STATE (%ebx) /* Thread_dis_alien */ jc 1f RESTORE_STATE sub $2, 4(%esp) /* Correct EIP to point to insn */ SC_ADDR_TO_ERR 2 2: pushl $0xd xchgl 4(%esp), %eax pusha jmp _slowtraps 1: /* do alien syscall and trap mafterwards */ RESET_THREAD_CANCEL_AT %ebx pushl %eax call *(%eax) /* call with ENABLED interrupts */ CHECK_SANITY $3 /* scratches ecx */ RESET_USER_SEGMENTS $3,no_cli /* scratches ecx */ popl %eax RESTORE_STATE SC_ADDR_TO_ERR 6 jmp 2b .p2align .globl leave_by_trigger_exception leave_by_trigger_exception: cli subl $12,%esp /* clean up stack from previous * CPL0-CPL0 iret */ pushl %eax pushl %ecx pushl %edx call thread_restore_exc_state popl %edx popl %ecx popl %eax pushl $0x00 pushl $0xff pusha jmp _slowtraps .section ".text.debug.stack_profiling" .global __cyg_profile_func_enter .global __cyg_profile_func_exit __ret_from_cyg: ret __cyg_profile_func_enter: __cyg_profile_func_exit: cmp $0xc0000000, %esp jl __ret_from_cyg cmp $0xd0000000,%esp jg __ret_from_cyg mov %esp, %ecx // and $0x7ff, %ecx /* 2K TCBs */ and $0xfff, %ecx /* 4K TCBs */ cmp $0x200, %ecx jg __ret_from_cyg int3 jmp 1f .ascii "STACK" 1: ret --------------040906060706040305090906 Content-Type: text/x-c++src; name="jdb_tbuf_events.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="jdb_tbuf_events.cpp" INTERFACE: #include "l4_types.h" class Log_patch { friend class Log_event; private: Log_patch *next; Unsigned8 *activator; }; class Log_event { const char *event_name; Log_patch *patch; int event_type; }; class Jdb_tbuf_events { public: static Log_event *const log_events[]; }; IMPLEMENTATION: #include #include "boot_info.h" #include "config.h" #include "jdb_ktrace.h" // The following headers are only included here to reflect the module // dependencies. // // patch_log_sched_invalidate // patch_log_sched_save // patch_log_sched_load // patch_log_context_switch #include "context.h" // patch_log_irq #include "dirq.h" // patch_log_pf_res // patch_log_trap // patch_log_thread_ex_regs // patch_log_timer_irq // patch_log_shortcut_failed1 // patch_log_shortcut_failed2 // patch_log_shortcut_succeeded #include "thread.h" // patch_show_log_pf_res #include "jdb_trace.h" // patch_show_log_context_switch // patch_show_log_shortcut #include "jdb_trace_set.h" // patch_log_send_preemption #include "preemption.h" #ifdef CONFIG_JDB_LOGGING #define DECLARE_PATCH(VAR, NAME) \ extern "C" char patch_##NAME; \ static Log_patch VAR(&patch_##NAME) // logging of context switch not implemented in Assembler shortcut but we // can switch to C shortcut DECLARE_PATCH (lp1, log_context_switch); DECLARE_PATCH (lp2, show_log_context_switch); static Log_event le1("context switch", Log_event_context_switch, 2, &lp1, &lp2); // logging of shortcut succeeded/failed not implemented in Assembler shortcut // but we can switch to C shortcut DECLARE_PATCH (lp3, log_shortcut_failed_1); DECLARE_PATCH (lp4, log_shortcut_failed_2); DECLARE_PATCH (lp5, log_shortcut_succeeded); DECLARE_PATCH (lp6, show_log_shortcut); static Log_event le2("ipc shortcut", Log_event_ipc_shortcut, 4, &lp3, &lp4, &lp5, &lp6); DECLARE_PATCH (lp7, log_irq); static Log_event le3("irq raised", Log_event_irq_raised, 1, &lp7); DECLARE_PATCH (lp8, log_timer_irq); static Log_event le4("timer irq raised", Log_event_timer_irq, 1, &lp8); DECLARE_PATCH (lp9, log_thread_ex_regs); #ifdef CONFIG_SYSCALL_ITER DECLARE_PATCH (lp10, log_thread_ex_regs_failed); static Log_event le5("thread_ex_regs", Log_event_thread_ex_regs, 2, &lp9, &lp10); #else static Log_event le5("thread_ex_regs", Log_event_thread_ex_regs, 1, &lp9); #endif #ifdef CONFIG_PF_UX DECLARE_PATCH (lp11, log_trap); static Log_event le6("trap raised", Log_event_trap, 1, &lp11); #else DECLARE_PATCH (lp11, log_trap); DECLARE_PATCH (lp12, log_trap_n); static Log_event le6("trap raised", Log_event_trap, 2, &lp11, &lp12); #endif DECLARE_PATCH (lp13, log_pf_res); DECLARE_PATCH (lp14, show_log_pf_res); static Log_event le7("pagefault result", Log_event_pf_res, 2, &lp13, &lp14); DECLARE_PATCH (lp15, log_sched_load); DECLARE_PATCH (lp16, log_sched_save); DECLARE_PATCH (lp17, log_sched_invalidate); static Log_event le8("scheduling event", Log_event_sched, 3, &lp15, &lp16, &lp17); DECLARE_PATCH (lp18, log_preemption); static Log_event le9("preemption sent", Log_event_preemption, 1, &lp18); DECLARE_PATCH (lp20, log_id_nearest); static Log_event le10("id_nearest", Log_event_id_nearest, 1, &lp20); DECLARE_PATCH (lp23, log_task_new); static Log_event le11("task_new", Log_event_task_new, 1, &lp23); Log_event * const Jdb_tbuf_events::log_events[Log_event_max] = { &le1, // context switch &le2, // ipc shortcut &le3, // irq raised &le4, // timer irq raised &le5, // thread_ex_regs &le6, // trap raised &le7, // pagefault result &le8, // scheduling event &le9, // preemption sent &le10, // id nearest &le11, // task new 0, // terminate list }; #endif PUBLIC explicit Log_event::Log_event(const char *name, int type, int count, Log_patch *lp, ...) { va_list args; Log_patch **p = &patch; va_start(args, lp); *p = lp; for (int i=0; inext; *p = va_arg(args, Log_patch*); } va_end(args); event_name = name; event_type = type; } // enable all patch entries of log event PUBLIC void Log_event::enable(int enable) { Log_patch *p = patch; while (p) { p->enable(enable); p = p->next; } } // log event enabled if first entry is enabled PUBLIC inline int Log_event::enabled(void) const { return patch->enabled(); } // get name of log event PUBLIC inline const char* Log_event::get_name(void) const { return event_name; } // get type of log event PUBLIC inline int Log_event::get_type(void) const { return event_type; } PUBLIC explicit Log_patch::Log_patch(void *code) : next(0), activator((Unsigned8*)code) { } PUBLIC void Log_patch::enable(int enable) { *activator = enable; // checksum has changed Boot_info::reset_checksum_ro(); } PUBLIC inline int Log_patch::enabled(void) { return *activator; } --------------040906060706040305090906 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --------------040906060706040305090906--